<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Spring Data JPA - Preface | Docs4dev</title>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use data access technologies.">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="true">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta property="og:type" content="website">
<meta property="og:title" content="Spring Data JPA - Preface">
<meta property="og:url" content="https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/">
<meta property="og:site_name" content="Docs4dev">
<meta property="og:locale" content="zh_CN">
<meta name="twitter:card" content="Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use data access technologies.">
<meta name="generator" content="Docs4dev template engine">
<link rel="stylesheet" href="static/css/app.min.css">
<link rel="shortcut icon" href="https://www.docs4dev.com/static/images/favicon.ico" type="image/x-icon">
<script async="" src="static/js/js.js"></script>
<script async="" src="static/js/adsbygoogle.js" crossorigin="anonymous"></script>
<script>
    window.dataLayer = window.dataLayer || [];

    function gtag() {
      dataLayer.push(arguments);
    }

    gtag('js', new Date());
    gtag('config', 'UA-129571937-1');
  </script>
<link rel="amphtml" href="https://www.docs4dev.com/amp/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/index.html">

<link rel="stylesheet" href="static/css/asciidoctor-spring.css">
<script type="application/ld+json">{"name":null,"headline":"Spring Data JPA-Preface","inLanguage":"en-US","version":"2.1.5.RELEASE","image":"/static/icon/icon-spring-data.png","datePublished":"2021-05-20T12:51:01Z","dateCreated":"2021-05-20T12:51:01Z","dateModified":"2021-07-03T12:24:35Z","@context":"https://schema.org/","@type":"APIReference","abstract":"Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use data access technologies."}</script>
</head>
<body>
<div class="book with-summary">
<div class="book-summary">
<div class="logo">
<a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference');" style="color: inherit;">
<img src="static/picture/icon-spring-data.png" style="width: 48px; height: 48px;" alt="Logo">
</a>
<b style="color: inherit; margin-left: 8px;">Spring Data JPA</b>
</div>
<div class="item">
<div>
<label for="version">版本</label>
<select id="version" onchange="onVersionChange(this)">
<option value="1.11.18.RELEASE">1.11.18.RELEASE</option>
<option value="2.0.13.RELEASE">2.0.13.RELEASE</option>
<option value="2.1.5.RELEASE" selected="selected">2.1.5.RELEASE</option>
</select>
</div>
<div style="margin-top: 8px;">
<label for="language">语言</label>
<select id="language" onchange="onLangChange(this)" value="en">
<option value="en" selected="selected">English</option>
<option value="zh">中文</option>
</select>
</div>

</div>
<div class="item menus">
<a title="Table of Contents" style="margin-right: 8px;" href="#">
<i class="fa fa-chevron-left"></i>
<span style="margin-left: 2px;">返回目录</span>
</a>
</div>
<nav role="navigation" id="navigation">
<ul class="summary">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#preface');" title="Preface"> Preface </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#project');" title="1. Project Metadata"> 1. Project Metadata </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#new-features');" title="2. New &amp; Noteworthy"> 2. New &amp; Noteworthy </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#new-features.1-11-0');" title="2.1. What’s New in Spring Data JPA 1.11"> 2.1. What’s New in Spring Data JPA 1.11 </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#new-features.1-10-0');" title="2.2. What’s New in Spring Data JPA 1.10"> 2.2. What’s New in Spring Data JPA 1.10 </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#dependencies');" title="3. Dependencies"> 3. Dependencies </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#dependencies.spring-boot');" title="3.1. Dependency Management with Spring Boot"> 3.1. Dependency Management with Spring Boot </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#dependencies.spring-framework');" title="3.2. Spring Framework"> 3.2. Spring Framework </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories');" title="4. Working with Spring Data Repositories"> 4. Working with Spring Data Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.core-concepts');" title="4.1. Core concepts"> 4.1. Core concepts </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-methods');" title="4.2. Query methods"> 4.2. Query methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.definition');" title="4.3. Defining Repository Interfaces"> 4.3. Defining Repository Interfaces </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.definition-tuning');" title="4.3.1. Fine-tuning Repository Definition"> 4.3.1. Fine-tuning Repository Definition </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.nullability');" title="4.3.2. Null Handling of Repository Methods"> 4.3.2. Null Handling of Repository Methods </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.multiple-modules');" title="4.3.3. Using Repositories with Multiple Spring Data Modules"> 4.3.3. Using Repositories with Multiple Spring Data Modules </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-methods.details');" title="4.4. Defining Query Methods"> 4.4. Defining Query Methods </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-methods.query-lookup-strategies');" title="4.4.1. Query Lookup Strategies"> 4.4.1. Query Lookup Strategies </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-methods.query-creation');" title="4.4.2. Query Creation"> 4.4.2. Query Creation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-methods.query-property-expressions');" title="4.4.3. Property Expressions"> 4.4.3. Property Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.special-parameters');" title="4.4.4. Special parameter handling"> 4.4.4. Special parameter handling </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.limit-query-result');" title="4.4.5. Limiting Query Results"> 4.4.5. Limiting Query Results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-streaming');" title="4.4.6. Streaming query results"> 4.4.6. Streaming query results </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.query-async');" title="4.4.7. Async query results"> 4.4.7. Async query results </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.create-instances');" title="4.5. Creating Repository Instances"> 4.5. Creating Repository Instances </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.create-instances.spring');" title="4.5.1. XML configuration"> 4.5.1. XML configuration </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.create-instances.java-config');" title="4.5.2. JavaConfig"> 4.5.2. JavaConfig </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.create-instances.standalone');" title="4.5.3. Standalone usage"> 4.5.3. Standalone usage </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.custom-implementations');" title="4.6. Custom Implementations for Spring Data Repositories"> 4.6. Custom Implementations for Spring Data Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.single-repository-behavior');" title="4.6.1. Customizing Individual Repositories"> 4.6.1. Customizing Individual Repositories </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.customize-base-repository');" title="4.6.2. Customize the Base Repository"> 4.6.2. Customize the Base Repository </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#core.domain-events');" title="4.7. Publishing Events from Aggregate Roots"> 4.7. Publishing Events from Aggregate Roots </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#core.extensions');" title="4.8. Spring Data Extensions"> 4.8. Spring Data Extensions </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#core.extensions.querydsl');" title="4.8.1. Querydsl Extension"> 4.8.1. Querydsl Extension </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#core.web');" title="4.8.2. Web support"> 4.8.2. Web support </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#core.repository-populators');" title="4.8.3. Repository Populators"> 4.8.3. Repository Populators </a> </li>
</ul> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#reference');" title="Reference Documentation"> Reference Documentation </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.repositories');" title="5. JPA Repositories"> 5. JPA Repositories </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.introduction');" title="5.1. Introduction"> 5.1. Introduction </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.namespace');" title="5.1.1. Spring Namespace"> 5.1.1. Spring Namespace </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.java-config');" title="5.1.2. Annotation-based Configuration"> 5.1.2. Annotation-based Configuration </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.bootstrap-mode');" title="5.1.3. Bootstrap Mode"> 5.1.3. Bootstrap Mode </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.entity-persistence');" title="5.2. Persisting Entities"> 5.2. Persisting Entities </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.entity-persistence.saving-entites');" title="5.2.1. Saving Entities"> 5.2.1. Saving Entities </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query-methods');" title="5.3. Query Methods"> 5.3. Query Methods </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.sample-app.finders.strategies');" title="5.3.1. Query Lookup Strategies"> 5.3.1. Query Lookup Strategies </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query-methods.query-creation');" title="5.3.2. Query Creation"> 5.3.2. Query Creation </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query-methods.named-queries');" title="5.3.3. Using JPA Named Queries"> 5.3.3. Using JPA Named Queries </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query-methods.at-query');" title="5.3.4. Using @Query"> 5.3.4. Using @Query </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query-methods.sorting');" title="5.3.5. Using Sort"> 5.3.5. Using Sort </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.named-parameters');" title="5.3.6. Using Named Parameters"> 5.3.6. Using Named Parameters </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query.spel-expressions');" title="5.3.7. Using SpEL Expressions"> 5.3.7. Using SpEL Expressions </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.modifying-queries');" title="5.3.8. Modifying Queries"> 5.3.8. Modifying Queries </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.query-hints');" title="5.3.9. Applying Query Hints"> 5.3.9. Applying Query Hints </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.entity-graph');" title="5.3.10. Configuring Fetch- and LoadGraphs"> 5.3.10. Configuring Fetch- and LoadGraphs </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#projections');" title="5.3.11. Projections"> 5.3.11. Projections </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.stored-procedures');" title="5.4. Stored Procedures"> 5.4. Stored Procedures </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#specifications');" title="5.5. Specifications"> 5.5. Specifications </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#query-by-example');" title="5.6. Query by Example"> 5.6. Query by Example </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#query-by-example.introduction');" title="5.6.1. Introduction"> 5.6.1. Introduction </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#query-by-example.usage');" title="5.6.2. Usage"> 5.6.2. Usage </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#query-by-example.matchers');" title="5.6.3. Example Matchers"> 5.6.3. Example Matchers </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#query-by-example.execution');" title="5.6.4. Executing an example"> 5.6.4. Executing an example </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#transactions');" title="5.7. Transactionality"> 5.7. Transactionality </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#transactional-query-methods');" title="5.7.1. Transactional query methods"> 5.7.1. Transactional query methods </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#locking');" title="5.8. Locking"> 5.8. Locking </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#auditing');" title="5.9. Auditing"> 5.9. Auditing </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#auditing.basics');" title="5.9.1. Basics"> 5.9.1. Basics </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.auditing');" title="5.9.2. JPA Auditing"> 5.9.2. JPA Auditing </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.misc');" title="5.10. Miscellaneous Considerations"> 5.10. Miscellaneous Considerations </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.misc.jpa-context');" title="5.10.1. Using JpaContext in Custom Implementations"> 5.10.1. Using JpaContext in Custom Implementations </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpa.misc.merging-persistence-units');" title="5.10.2. Merging persistence units"> 5.10.2. Merging persistence units </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#jpd.misc.cdi-integration');" title="5.10.3. CDI Integration"> 5.10.3. CDI Integration </a> </li>
</ul> </li>
</ul> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#appendix');" title="Appendix"> Appendix </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repositories.namespace-reference');" title="Appendix A: Namespace reference"> Appendix A: Namespace reference </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#populator.namespace-dao-config');" title="The <repositories /> Element"> The &lt;repositories /&gt; Element </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#populator.namespace-reference');" title="Appendix B: Populators namespace reference"> Appendix B: Populators namespace reference </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#namespace-dao-config');" title="The <populator /> element"> The &lt;populator /&gt; element </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repository-query-keywords');" title="Appendix C: Repository query keywords"> Appendix C: Repository query keywords </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#_supported_query_keywords');" title="Supported query keywords"> Supported query keywords </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#repository-query-return-types');" title="Appendix D: Repository query return types"> Appendix D: Repository query return types </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#_supported_query_return_types');" title="Supported Query Return Types"> Supported Query Return Types </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#faq');" title="Appendix E: Frequently Asked Questions"> Appendix E: Frequently Asked Questions </a>
<ul class="articles">
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#_common');" title="Common"> Common </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#_infrastructure');" title="Infrastructure"> Infrastructure </a> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#_auditing');" title="Auditing"> Auditing </a> </li>
</ul> </li>
<li class="chapter"> <a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-data-jpa/2.1.5.RELEASE/reference/all.html#glossary');" title="Appendix F: Glossary"> Appendix F: Glossary </a> </li>
</ul> </li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<header class="book-header">
<div class="dropdown pull-right js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-globe"></i>
</a>
<div class="dropdown-menu dropdown-left">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('zh_CN')">中文</button>
</div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('en_US')">English</button>
</div>
</div>
</div>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign up" href="register.html">
<i class="fa fa-sign-in"></i> <span>注册</span>
</a>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign in" href="register.html">
<i class="fa fa-sign-in"></i>
<span>登录</span>
</a>
<a class="btn pull-left js-toolbar-action btn-summary" href="#"><i class="fa fa-align-justify"></i></a>
<div class="dropdown pull-left font-settings js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Font Settings" href="#">
<i class="fa fa-font"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-2 font-reduce">A</button>
<button class="button size-2 font-enlarge">A</button>
</div>
<div class="buttons">
<button class="button size-2 family-serif">Serif</button>
<button class="button size-2 family-sans">Sans</button>
</div>
<div class="buttons">
<button class="button size-3 theme-white">White</button>
<button class="button size-3 theme-sepia">Sepia</button>
<button class="button size-3 theme-night">Night</button>
</div>
</div>
</div>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
<div class="dropdown pull-left js-toolbar-action mobile">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-chevron-down"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<a class="button size-1" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
</div>
</div>
</div>
<div id="autocomplete" class="pull-right"></div>
<span id="toolbar-title"></span>
</header>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal markdown-section">
<div id="content">
<h1>Preface</h1>
<div><ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-6108808167664152" data-ad-slot="6964403648"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<div><div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>© 2008-2019 The original authors.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. </td>
</tr>
</tbody>
</table>
</div>
<div id="toc" class="toc">
<div id="toctitle" class="title">
Table of Contents
</div>
<ul class="sectlevel0">
<li><a href="#preface">Preface</a>
<ul class="sectlevel1">
<li><a href="#project">1. Project Metadata</a></li>
<li><a href="#new-features">2. New &amp; Noteworthy</a>
<ul class="sectlevel2">
<li><a href="#new-features.1-11-0">2.1. What’s New in Spring Data JPA 1.11</a></li>
<li><a href="#new-features.1-10-0">2.2. What’s New in Spring Data JPA 1.10</a></li>
</ul> </li>
<li><a href="#dependencies">3. Dependencies</a>
<ul class="sectlevel2">
<li><a href="#dependencies.spring-boot">3.1. Dependency Management with Spring Boot</a></li>
<li><a href="#dependencies.spring-framework">3.2. Spring Framework</a></li>
</ul> </li>
<li><a href="#repositories">4. Working with Spring Data Repositories</a>
<ul class="sectlevel2">
<li><a href="#repositories.core-concepts">4.1. Core concepts</a></li>
<li><a href="#repositories.query-methods">4.2. Query methods</a></li>
<li><a href="#repositories.definition">4.3. Defining Repository Interfaces</a>
<ul class="sectlevel3">
<li><a href="#repositories.definition-tuning">4.3.1. Fine-tuning Repository Definition</a></li>
<li><a href="#repositories.nullability">4.3.2. Null Handling of Repository Methods</a></li>
<li><a href="#repositories.multiple-modules">4.3.3. Using Repositories with Multiple Spring Data Modules</a></li>
</ul> </li>
<li><a href="#repositories.query-methods.details">4.4. Defining Query Methods</a>
<ul class="sectlevel3">
<li><a href="#repositories.query-methods.query-lookup-strategies">4.4.1. Query Lookup Strategies</a></li>
<li><a href="#repositories.query-methods.query-creation">4.4.2. Query Creation</a></li>
<li><a href="#repositories.query-methods.query-property-expressions">4.4.3. Property Expressions</a></li>
<li><a href="#repositories.special-parameters">4.4.4. Special parameter handling</a></li>
<li><a href="#repositories.limit-query-result">4.4.5. Limiting Query Results</a></li>
<li><a href="#repositories.query-streaming">4.4.6. Streaming query results</a></li>
<li><a href="#repositories.query-async">4.4.7. Async query results</a></li>
</ul> </li>
<li><a href="#repositories.create-instances">4.5. Creating Repository Instances</a>
<ul class="sectlevel3">
<li><a href="#repositories.create-instances.spring">4.5.1. XML configuration</a></li>
<li><a href="#repositories.create-instances.java-config">4.5.2. JavaConfig</a></li>
<li><a href="#repositories.create-instances.standalone">4.5.3. Standalone usage</a></li>
</ul> </li>
<li><a href="#repositories.custom-implementations">4.6. Custom Implementations for Spring Data Repositories</a>
<ul class="sectlevel3">
<li><a href="#repositories.single-repository-behavior">4.6.1. Customizing Individual Repositories</a></li>
<li><a href="#repositories.customize-base-repository">4.6.2. Customize the Base Repository</a></li>
</ul> </li>
<li><a href="#core.domain-events">4.7. Publishing Events from Aggregate Roots</a></li>
<li><a href="#core.extensions">4.8. Spring Data Extensions</a>
<ul class="sectlevel3">
<li><a href="#core.extensions.querydsl">4.8.1. Querydsl Extension</a></li>
<li><a href="#core.web">4.8.2. Web support</a></li>
<li><a href="#core.repository-populators">4.8.3. Repository Populators</a></li>
</ul> </li>
</ul> </li>
</ul> </li>
<li><a href="#reference">Reference Documentation</a>
<ul class="sectlevel1">
<li><a href="#jpa.repositories">5. JPA Repositories</a>
<ul class="sectlevel2">
<li><a href="#jpa.introduction">5.1. Introduction</a>
<ul class="sectlevel3">
<li><a href="#jpa.namespace">5.1.1. Spring Namespace</a></li>
<li><a href="#jpa.java-config">5.1.2. Annotation-based Configuration</a></li>
<li><a href="#jpa.bootstrap-mode">5.1.3. Bootstrap Mode</a></li>
</ul> </li>
<li><a href="#jpa.entity-persistence">5.2. Persisting Entities</a>
<ul class="sectlevel3">
<li><a href="#jpa.entity-persistence.saving-entites">5.2.1. Saving Entities</a></li>
</ul> </li>
<li><a href="#jpa.query-methods">5.3. Query Methods</a>
<ul class="sectlevel3">
<li><a href="#jpa.sample-app.finders.strategies">5.3.1. Query Lookup Strategies</a></li>
<li><a href="#jpa.query-methods.query-creation">5.3.2. Query Creation</a></li>
<li><a href="#jpa.query-methods.named-queries">5.3.3. Using JPA Named Queries</a></li>
<li><a href="#jpa.query-methods.at-query">5.3.4. Using <code class="notranslate">@Query</code></a></li>
<li><a href="#jpa.query-methods.sorting">5.3.5. Using Sort</a></li>
<li><a href="#jpa.named-parameters">5.3.6. Using Named Parameters</a></li>
<li><a href="#jpa.query.spel-expressions">5.3.7. Using SpEL Expressions</a></li>
<li><a href="#jpa.modifying-queries">5.3.8. Modifying Queries</a></li>
<li><a href="#jpa.query-hints">5.3.9. Applying Query Hints</a></li>
<li><a href="#jpa.entity-graph">5.3.10. Configuring Fetch- and LoadGraphs</a></li>
<li><a href="#projections">5.3.11. Projections</a></li>
</ul> </li>
<li><a href="#jpa.stored-procedures">5.4. Stored Procedures</a></li>
<li><a href="#specifications">5.5. Specifications</a></li>
<li><a href="#query-by-example">5.6. Query by Example</a>
<ul class="sectlevel3">
<li><a href="#query-by-example.introduction">5.6.1. Introduction</a></li>
<li><a href="#query-by-example.usage">5.6.2. Usage</a></li>
<li><a href="#query-by-example.matchers">5.6.3. Example Matchers</a></li>
<li><a href="#query-by-example.execution">5.6.4. Executing an example</a></li>
</ul> </li>
<li><a href="#transactions">5.7. Transactionality</a>
<ul class="sectlevel3">
<li><a href="#transactional-query-methods">5.7.1. Transactional query methods</a></li>
</ul> </li>
<li><a href="#locking">5.8. Locking</a></li>
<li><a href="#auditing">5.9. Auditing</a>
<ul class="sectlevel3">
<li><a href="#auditing.basics">5.9.1. Basics</a></li>
<li><a href="#jpa.auditing">5.9.2. JPA Auditing</a></li>
</ul> </li>
<li><a href="#jpa.misc">5.10. Miscellaneous Considerations</a>
<ul class="sectlevel3">
<li><a href="#jpa.misc.jpa-context">5.10.1. Using <code class="notranslate">JpaContext</code> in Custom Implementations</a></li>
<li><a href="#jpa.misc.merging-persistence-units">5.10.2. Merging persistence units</a></li>
<li><a href="#jpd.misc.cdi-integration">5.10.3. CDI Integration</a></li>
</ul> </li>
</ul> </li>
</ul> </li>
<li><a href="#appendix">Appendix</a>
<ul class="sectlevel1">
<li><a href="#repositories.namespace-reference">Appendix A: Namespace reference</a>
<ul class="sectlevel2">
<li><a href="#populator.namespace-dao-config">The <code class="notranslate">&lt;repositories /&gt;</code> Element</a></li>
</ul> </li>
<li><a href="#populator.namespace-reference">Appendix B: Populators namespace reference</a>
<ul class="sectlevel2">
<li><a href="#namespace-dao-config">The &lt;populator /&gt; element</a></li>
</ul> </li>
<li><a href="#repository-query-keywords">Appendix C: Repository query keywords</a>
<ul class="sectlevel2">
<li><a href="#_supported_query_keywords">Supported query keywords</a></li>
</ul> </li>
<li><a href="#repository-query-return-types">Appendix D: Repository query return types</a>
<ul class="sectlevel2">
<li><a href="#_supported_query_return_types">Supported Query Return Types</a></li>
</ul> </li>
<li><a href="#faq">Appendix E: Frequently Asked Questions</a>
<ul class="sectlevel2">
<li><a href="#_common">Common</a></li>
<li><a href="#_infrastructure">Infrastructure</a></li>
<li><a href="#_auditing">Auditing</a></li>
</ul> </li>
<li><a href="#glossary">Appendix F: Glossary</a></li>
</ul> </li>
</ul>
</div>
</div>
</div>
<div class="openblock partintro">
<div class="content">
Spring Data JPA provides repository support for the Java Persistence API (JPA). It eases development of applications that need to access JPA data sources.
</div>
</div>
<div class="sect1">
<h2 id="project"><a class="anchor" href="#project"></a>1. Project Metadata</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li> <p>Version control - <a href="javascript:window.open('https://github.com/spring-projects/spring-data-jpa');" class="bare" target="_blank" rel="noopener noreferrer">http://github.com/spring-projects/spring-data-jpa <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Bugtracker - <a href="javascript:window.open('https://jira.spring.io/browse/DATAJPA');" class="bare" target="_blank" rel="noopener noreferrer">https://jira.spring.io/browse/DATAJPA <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Release repository - <a href="javascript:window.open('https://repo.spring.io/libs-release');" class="bare" target="_blank" rel="noopener noreferrer">https://repo.spring.io/libs-release <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Milestone repository - <a href="javascript:window.open('https://repo.spring.io/libs-milestone');" class="bare" target="_blank" rel="noopener noreferrer">https://repo.spring.io/libs-milestone <i class="fa fa-external-link"></i></a></p> </li>
<li> <p>Snapshot repository - <a href="javascript:window.open('https://repo.spring.io/libs-snapshot');" class="bare" target="_blank" rel="noopener noreferrer">https://repo.spring.io/libs-snapshot <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="new-features"><a class="anchor" href="#new-features"></a>2. New &amp; Noteworthy</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="new-features.1-11-0"><a class="anchor" href="#new-features.1-11-0"></a>2.1. What’s New in Spring Data JPA 1.11</h3>
<div class="paragraph">
<p>Spring Data JPA 1.11 added the following features:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Improved compatibility with Hibernate 5.2.</p> </li>
<li> <p>Support any-match mode for <a href="#query-by-example">Query by Example</a>.</p> </li>
<li> <p>Paged query execution optimizations.</p> </li>
<li> <p>Support for the <code class="notranslate">exists</code> projection in repository query derivation.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-10-0"><a class="anchor" href="#new-features.1-10-0"></a>2.2. What’s New in Spring Data JPA 1.10</h3>
<div class="paragraph">
<p>Spring Data JPA 1.10 added the following features:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Support for <a href="#projections">Projections</a> in repository query methods.</p> </li>
<li> <p>Support for <a href="#query-by-example">Query by Example</a>.</p> </li>
<li> <p>The following annotations have been enabled to build on composed annotations: <code class="notranslate">@EntityGraph</code>, <code class="notranslate">@Lock</code>, <code class="notranslate">@Modifying</code>, <code class="notranslate">@Query</code>, <code class="notranslate">@QueryHints</code>, and <code class="notranslate">@Procedure</code>.</p> </li>
<li> <p>Support for the <code class="notranslate">Contains</code> keyword on collection expressions.</p> </li>
<li> <p><code class="notranslate">AttributeConverter</code> implementations for <code class="notranslate">ZoneId</code> of JSR-310 and ThreeTenBP.</p> </li>
<li> <p>Upgrade to Querydsl 4, Hibernate 5, OpenJPA 2.4, and EclipseLink 2.6.1.</p> </li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dependencies"><a class="anchor" href="#dependencies"></a>3. Dependencies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Due to the different inception dates of individual Spring Data modules, most of them carry different major and minor version numbers. The easiest way to find compatible ones is to rely on the Spring Data Release Train BOM that we ship with the compatible versions defined. In a Maven project, you would declare this dependency in the <code class="notranslate">&lt;dependencyManagement /&gt;</code> section of your POM, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 1. Using the Spring Data release train BOM
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;dependencyManagement&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
      &lt;artifactId&gt;spring-data-releasetrain&lt;/artifactId&gt;
      &lt;version&gt;Lovelace-SR5&lt;/version&gt;
      &lt;scope&gt;import&lt;/scope&gt;
      &lt;type&gt;pom&lt;/type&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre>
</div>
</div>
</div>
</div>
<div id="dependencies.train-names" class="paragraph">
<p>The current release train version is <code class="notranslate">Lovelace-SR5</code>. The train names ascend alphabetically and the currently available trains are listed <a href="javascript:window.open('https://github.com/spring-projects/spring-data-commons/wiki/Release-planning');" target="_blank" rel="noopener noreferrer">here <i class="fa fa-external-link"></i></a>. The version name follows the following pattern: <code class="notranslate">${name}-${release}</code>, where release can be one of the following:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">BUILD-SNAPSHOT</code>: Current snapshots</p> </li>
<li> <p><code class="notranslate">M1</code>, <code class="notranslate">M2</code>, and so on: Milestones</p> </li>
<li> <p><code class="notranslate">RC1</code>, <code class="notranslate">RC2</code>, and so on: Release candidates</p> </li>
<li> <p><code class="notranslate">RELEASE</code>: GA release</p> </li>
<li> <p><code class="notranslate">SR1</code>, <code class="notranslate">SR2</code>, and so on: Service releases</p> </li>
</ul>
</div>
<div class="paragraph">
<p>A working example of using the BOMs can be found in our <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples/tree/master/bom');" target="_blank" rel="noopener noreferrer">Spring Data examples repository <i class="fa fa-external-link"></i></a>. With that in place, you can declare the Spring Data modules you would like to use without a version in the <code class="notranslate">&lt;dependencies /&gt;</code> block, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 2. Declaring a dependency to a Spring Data module
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;dependencies&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
    &lt;artifactId&gt;spring-data-jpa&lt;/artifactId&gt;
  &lt;/dependency&gt;
&lt;dependencies&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-boot"><a class="anchor" href="#dependencies.spring-boot"></a>3.1. Dependency Management with Spring Boot</h3>
<div class="paragraph">
<p>Spring Boot selects a recent version of Spring Data modules for you. If you still want to upgrade to a newer version, configure the property <code class="notranslate">spring-data-releasetrain.version</code> to the <a href="#dependencies.train-names">train name and iteration</a> you would like to use.</p>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-framework"><a class="anchor" href="#dependencies.spring-framework"></a>3.2. Spring Framework</h3>
<div class="paragraph">
<p>The current version of Spring Data modules require Spring Framework in version 5.1.5.RELEASE or better. The modules might also work with an older bugfix version of that minor version. However, using the most recent version within that generation is highly recommended.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="repositories"><a class="anchor" href="#repositories"></a>4. Working with Spring Data Repositories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.</p>
 </div>
<div class="admonitionblock important">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-important" title="Important"></i> </td>
<td class="content">
<div class="paragraph">
<p><em>Spring Data repository documentation and your module</em></p>
</div>
<div class="paragraph">
<p>This chapter explains the core concepts and interfaces of Spring Data repositories. The information in this chapter is pulled from the Spring Data Commons module. It uses the configuration and code samples for the Java Persistence API (JPA) module. You should adapt the XML namespace declaration and the types to be extended to the equivalents of the particular module that you use. “<a href="#repositories.namespace-reference">Namespace reference</a>” covers XML configuration, which is supported across all Spring Data modules supporting the repository API. “<a href="#repository-query-keywords">Repository query keywords</a>” covers the query method keywords supported by the repository abstraction in general. For detailed information on the specific features of your module, see the chapter on that module of this document.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="repositories.core-concepts"><a class="anchor" href="#repositories.core-concepts"></a>4.1. Core concepts</h3>
<div class="paragraph">
<p>The central interface in the Spring Data repository abstraction is <code class="notranslate">Repository</code>. It takes the domain class to manage as well as the ID type of the domain class as type arguments. This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The <code class="notranslate">CrudRepository</code> provides sophisticated CRUD functionality for the entity class that is being managed.</p>
</div>
<div id="repositories.repository" class="exampleblock">
<div class="title">
Example 3.
<code class="notranslate">CrudRepository</code> interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface CrudRepository&lt;T, ID extends Serializable&gt;
  extends Repository&lt;T, ID&gt; {

  &lt;S extends T&gt; S save(S entity);      <i class="conum" data-value="1"></i><b>(1)</b>

  Optional&lt;T&gt; findById(ID primaryKey); <i class="conum" data-value="2"></i><b>(2)</b>

  Iterable&lt;T&gt; findAll();               <i class="conum" data-value="3"></i><b>(3)</b>

  long count();                        <i class="conum" data-value="4"></i><b>(4)</b>

  void delete(T entity);               <i class="conum" data-value="5"></i><b>(5)</b>

  boolean existsById(ID primaryKey);   <i class="conum" data-value="6"></i><b>(6)</b>

  // … more functionality omitted.
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Saves the given entity.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Returns the entity identified by the given ID.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns all entities.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns the number of entities.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>Deletes the given entity.</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b class="notranslate">6</b></td>
<td>Indicates whether an entity with the given ID exists.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> We also provide persistence technology-specific abstractions, such as <code class="notranslate">JpaRepository</code> or <code class="notranslate">MongoRepository</code>. Those interfaces extend <code class="notranslate">CrudRepository</code> and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as <code class="notranslate">CrudRepository</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>On top of the <code class="notranslate">CrudRepository</code>, there is a <code class="notranslate">PagingAndSortingRepository</code> abstraction that adds additional methods to ease paginated access to entities:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 4.
<code class="notranslate">PagingAndSortingRepository</code> interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface PagingAndSortingRepository&lt;T, ID extends Serializable&gt;
  extends CrudRepository&lt;T, ID&gt; {

  Iterable&lt;T&gt; findAll(Sort sort);

  Page&lt;T&gt; findAll(Pageable pageable);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To access the second page of <code class="notranslate">User</code> by a page size of 20, you could do something like the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">PagingAndSortingRepository&lt;User, Long&gt; repository = // … get access to a bean
Page&lt;User&gt; users = repository.findAll(PageRequest.of(1, 20));</code></pre>
</div>
</div>
<div class="paragraph">
<p>In addition to query methods, query derivation for both count and delete queries is available. The following list shows the interface definition for a derived count query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 5. Derived Count Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  long countByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following list shows the interface definition for a derived delete query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 6. Derived Delete Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt; {

  long deleteByLastname(String lastname);

  List&lt;User&gt; removeByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.query-methods"><a class="anchor" href="#repositories.query-methods"></a>4.2. Query methods</h3>
<div class="paragraph">
<p>Standard CRUD functionality repositories usually have queries on the underlying datastore. With Spring Data, declaring those queries becomes a four-step process:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>Declare an interface extending Repository or one of its subinterfaces and type it to the domain class and ID type that it should handle, as shown in the following example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; { … }</code></pre>
</div>
</div> </li>
<li> <p>Declare query methods on the interface.</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {
  List&lt;Person&gt; findByLastname(String lastname);
}</code></pre>
</div>
</div> </li>
<li> <p>Set up Spring to create proxy instances for those interfaces, either with <a href="#repositories.create-instances.java-config">JavaConfig</a> or with <a href="#repositories.create-instances">XML configuration</a>.</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li> <p>To use Java configuration, create a class similar to the following:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
class Config {}</code></pre>
</div>
</div> </li>
<li> <p>To use XML configuration, define a bean similar to the following:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jpa="http://www.springframework.org/schema/data/jpa"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/data/jpa
     http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

   &lt;jpa:repositories base-package="com.acme.repositories"/&gt;

&lt;/beans&gt;</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The JPA namespace is used in this example. If you use the repository abstraction for any other store, you need to change this to the appropriate namespace declaration of your store module. In other words, you should exchange <code class="notranslate">jpa</code> in favor of, for example, <code class="notranslate">mongodb</code>.</p>
</div>
<div class="paragraph">
<p>+ Also, note that the JavaConfig variant does not configure a package explicitly, because the package of the annotated class is used by default. To customize the package to scan, use one of the <code class="notranslate">basePackage…</code> attributes of the data-store-specific repository’s <code class="notranslate">@Enable${store}Repositories</code>-annotation.</p>
</div> </li>
<li> <p>Inject the repository instance and use it, as shown in the following example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class SomeClient {

  private final PersonRepository repository;

  SomeClient(PersonRepository repository) {
    this.repository = repository;
  }

  void doSomething() {
    List&lt;Person&gt; persons = repository.findByLastname("Matthews");
  }
}</code></pre>
</div>
</div> </li>
</ol>
</div>
<div class="paragraph">
<p>The sections that follow explain each step in detail:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="#repositories.definition">Defining Repository Interfaces</a></p> </li>
<li> <p><a href="#repositories.query-methods.details">Defining Query Methods</a></p> </li>
<li> <p><a href="#repositories.create-instances">Creating Repository Instances</a></p> </li>
<li> <p><a href="#repositories.custom-implementations">Custom Implementations for Spring Data Repositories</a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="repositories.definition"><a class="anchor" href="#repositories.definition"></a>4.3. Defining Repository Interfaces</h3>
<div class="paragraph">
<p>First, define a domain class-specific repository interface. The interface must extend <code class="notranslate">Repository</code> and be typed to the domain class and an ID type. If you want to expose CRUD methods for that domain type, extend <code class="notranslate">CrudRepository</code> instead of <code class="notranslate">Repository</code>.</p>
</div>
<div class="sect3">
<h4 id="repositories.definition-tuning"><a class="anchor" href="#repositories.definition-tuning"></a>4.3.1. Fine-tuning Repository Definition</h4>
<div class="paragraph">
<p>Typically, your repository interface extends <code class="notranslate">Repository</code>, <code class="notranslate">CrudRepository</code>, or <code class="notranslate">PagingAndSortingRepository</code>. Alternatively, if you do not want to extend Spring Data interfaces, you can also annotate your repository interface with <code class="notranslate">@RepositoryDefinition</code>. Extending <code class="notranslate">CrudRepository</code> exposes a complete set of methods to manipulate your entities. If you prefer to be selective about the methods being exposed, copy the methods you want to expose from <code class="notranslate">CrudRepository</code> into your domain repository.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Doing so lets you define your own abstractions on top of the provided Spring Data Repositories functionality. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The following example shows how to selectively expose CRUD methods (<code class="notranslate">findById</code> and <code class="notranslate">save</code>, in this case):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 7. Selectively exposing CRUD methods
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@NoRepositoryBean
interface MyBaseRepository&lt;T, ID extends Serializable&gt; extends Repository&lt;T, ID&gt; {

  Optional&lt;T&gt; findById(ID id);

  &lt;S extends T&gt; S save(S entity);
}

interface UserRepository extends MyBaseRepository&lt;User, Long&gt; {
  User findByEmailAddress(EmailAddress emailAddress);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the prior example, you defined a common base interface for all your domain repositories and exposed <code class="notranslate">findById(…)</code> as well as <code class="notranslate">save(…)</code>.These methods are routed into the base repository implementation of the store of your choice provided by Spring Data (for example, if you use JPA, the implementation is <code class="notranslate">SimpleJpaRepository</code>), because they match the method signatures in <code class="notranslate">CrudRepository</code>. So the <code class="notranslate">UserRepository</code> can now save users, find individual users by ID, and trigger a query to find <code class="notranslate">Users</code> by email address.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The intermediate repository interface is annotated with <code class="notranslate">@NoRepositoryBean</code>. Make sure you add that annotation to all repository interfaces for which Spring Data should not create instances at runtime. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.nullability"><a class="anchor" href="#repositories.nullability"></a>4.3.2. Null Handling of Repository Methods</h4>
<div class="paragraph">
<p>As of Spring Data 2.0, repository CRUD methods that return an individual aggregate instance use Java 8’s <code class="notranslate">Optional</code> to indicate the potential absence of a value. Besides that, Spring Data supports returning the following wrapper types on query methods:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">com.google.common.base.Optional</code></p> </li>
<li> <p><code class="notranslate">scala.Option</code></p> </li>
<li> <p><code class="notranslate">io.vavr.control.Option</code></p> </li>
<li> <p><code class="notranslate">javaslang.control.Option</code> (deprecated as Javaslang is deprecated)</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Alternatively, query methods can choose not to use a wrapper type at all. The absence of a query result is then indicated by returning <code class="notranslate">null</code>. Repository methods returning collections, collection alternatives, wrappers, and streams are guaranteed never to return <code class="notranslate">null</code> but rather the corresponding empty representation. See “<a href="#repository-query-return-types">Repository query return types</a>” for details.</p>
</div>
<div class="sect4">
<h5 id="repositories.nullability.annotations"><a class="anchor" href="#repositories.nullability.annotations"></a>Nullability Annotations</h5>
<div class="paragraph">
<p>You can express nullability constraints for repository methods by using <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#null-safety');" target="_blank" rel="noopener noreferrer">Spring Framework’s nullability annotations <i class="fa fa-external-link"></i></a>. They provide a tooling-friendly approach and opt-in <code class="notranslate">null</code> checks during runtime, as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/org/springframework/lang/NonNullApi.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@NonNullApi</code> <i class="fa fa-external-link"></i></a>: Used on the package level to declare that the default behavior for parameters and return values is to not accept or produce <code class="notranslate">null</code> values.</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/org/springframework/lang/NonNull.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@NonNull</code> <i class="fa fa-external-link"></i></a>: Used on a parameter or return value that must not be <code class="notranslate">null</code> (not needed on a parameter and return value where <code class="notranslate">@NonNullApi</code> applies).</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/org/springframework/lang/Nullable.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">@Nullable</code> <i class="fa fa-external-link"></i></a>: Used on a parameter or return value that can be <code class="notranslate">null</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Spring annotations are meta-annotated with <a href="javascript:window.open('https://jcp.org/en/jsr/detail?id=305');" target="_blank" rel="noopener noreferrer">JSR 305 <i class="fa fa-external-link"></i></a> annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors such as <a href="javascript:window.open('https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html');" target="_blank" rel="noopener noreferrer">IDEA <i class="fa fa-external-link"></i></a>, <a href="javascript:window.open('https://help.eclipse.org/oxygen/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm');" target="_blank" rel="noopener noreferrer">Eclipse <i class="fa fa-external-link"></i></a>, and <a href="javascript:window.open('https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types');" target="_blank" rel="noopener noreferrer">Kotlin <i class="fa fa-external-link"></i></a> provide null-safety support in a generic way, without having to hard-code support for Spring annotations. To enable runtime checking of nullability constraints for query methods, you need to activate non-nullability on the package level by using Spring’s <code class="notranslate">@NonNullApi</code> in <code class="notranslate">package-info.java</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 8. Declaring Non-nullability in
<code class="notranslate">package-info.java</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@org.springframework.lang.NonNullApi
package com.acme;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Once non-null defaulting is in place, repository query method invocations get validated at runtime for nullability constraints. If a query execution result violates the defined constraint, an exception is thrown. This happens when the method would return <code class="notranslate">null</code> but is declared as non-nullable (the default with the annotation defined on the package the repository resides in). If you want to opt-in to nullable results again, selectively use <code class="notranslate">@Nullable</code> on individual methods. Using the result wrapper types mentioned at the start of this section continues to work as expected: An empty result is translated into the value that represents absence.</p>
</div>
<div class="paragraph">
<p>The following example shows a number of the techniques just described:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 9. Using different nullability constraints
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">package com.acme;                                                       <i class="conum" data-value="1"></i><b>(1)</b>

import org.springframework.lang.Nullable;

interface UserRepository extends Repository&lt;User, Long&gt; {

  User getByEmailAddress(EmailAddress emailAddress);                    <i class="conum" data-value="2"></i><b>(2)</b>

  @Nullable
  User findByEmailAddress(@Nullable EmailAddress emailAdress);          <i class="conum" data-value="3"></i><b>(3)</b>

  Optional&lt;User&gt; findOptionalByEmailAddress(EmailAddress emailAddress); <i class="conum" data-value="4"></i><b>(4)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The repository resides in a package (or sub-package) for which we have defined non-null behavior.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Throws an <code class="notranslate">EmptyResultDataAccessException</code> when the query executed does not produce a result. Throws an <code class="notranslate">IllegalArgumentException</code> when the <code class="notranslate">emailAddress</code> handed to the method is <code class="notranslate">null</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
 <td>Returns <code class="notranslate">null</code> when the query executed does not produce a result. Also accepts <code class="notranslate">null</code> as the value for <code class="notranslate">emailAddress</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns <code class="notranslate">Optional.empty()</code> when the query executed does not produce a result. Throws an <code class="notranslate">IllegalArgumentException</code> when the <code class="notranslate">emailAddress</code> handed to the method is <code class="notranslate">null</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="repositories.nullability.kotlin"><a class="anchor" href="#repositories.nullability.kotlin"></a>Nullability in Kotlin-based Repositories</h5>
<div class="paragraph">
<p>Kotlin has the definition of <a href="javascript:window.open('https://kotlinlang.org/docs/reference/null-safety.html');" target="_blank" rel="noopener noreferrer">nullability constraints <i class="fa fa-external-link"></i></a> baked into the language. Kotlin code compiles to bytecode, which does not express nullability constraints through method signatures but rather through compiled-in metadata. Make sure to include the <code class="notranslate">kotlin-reflect</code> JAR in your project to enable introspection of Kotlin’s nullability constraints. Spring Data repositories use the language mechanism to define those constraints to apply the same runtime checks, as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 10. Using nullability constraints on Kotlin repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-kotlin" data-lang="kotlin">interface UserRepository : Repository&lt;User, String&gt; {

  fun findByUsername(username: String): User     <i class="conum" data-value="1"></i><b>(1)</b>

  fun findByFirstname(firstname: String?): User? <i class="conum" data-value="2"></i><b>(2)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The method defines both the parameter and the result as non-nullable (the Kotlin default). The Kotlin compiler rejects method invocations that pass <code class="notranslate">null</code> to the method. If the query execution yields an empty result, an <code class="notranslate">EmptyResultDataAccessException</code> is thrown.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>This method accepts <code class="notranslate">null</code> for the <code class="notranslate">firstname</code> parameter and returns <code class="notranslate">null</code> if the query execution does not produce a result.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.multiple-modules"><a class="anchor" href="#repositories.multiple-modules"></a>4.3.3. Using Repositories with Multiple Spring Data Modules</h4>
<div class="paragraph">
<p>Using a unique Spring Data module in your application makes things simple, because all repository interfaces in the defined scope are bound to the Spring Data module. Sometimes, applications require using more than one Spring Data module. In such cases, a repository definition must distinguish between persistence technologies. When it detects multiple repository factories on the class path, Spring Data enters strict repository configuration mode. Strict configuration uses details on the repository or the domain class to decide about Spring Data module binding for a repository definition:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>If the repository definition <a href="#repositories.multiple-modules.types">extends the module-specific repository</a>, then it is a valid candidate for the particular Spring Data module.</p> </li>
<li> <p>If the domain class is <a href="#repositories.multiple-modules.annotations">annotated with the module-specific type annotation</a>, then it is a valid candidate for the particular Spring Data module. Spring Data modules accept either third-party annotations (such as JPA’s <code class="notranslate">@Entity</code>) or provide their own annotations (such as <code class="notranslate">@Document</code> for Spring Data MongoDB and Spring Data Elasticsearch).</p> </li>
</ol>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses module-specific interfaces (JPA in this case):</p>
</div>
<div id="repositories.multiple-modules.types" class="exampleblock">
<div class="title">
Example 11. Repository definitions using module-specific interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface MyRepository extends JpaRepository&lt;User, Long&gt; { }

@NoRepositoryBean
interface MyBaseRepository&lt;T, ID extends Serializable&gt; extends JpaRepository&lt;T, ID&gt; {
  …
}

interface UserRepository extends MyBaseRepository&lt;User, Long&gt; {
  …
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">MyRepository</code> and <code class="notranslate">UserRepository</code> extend <code class="notranslate">JpaRepository</code> in their type hierarchy. They are valid candidates for the Spring Data JPA module.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses generic interfaces:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 12. Repository definitions using generic interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface AmbiguousRepository extends Repository&lt;User, Long&gt; {
 …
}

@NoRepositoryBean
interface MyBaseRepository&lt;T, ID extends Serializable&gt; extends CrudRepository&lt;T, ID&gt; {
  …
}

interface AmbiguousUserRepository extends MyBaseRepository&lt;User, Long&gt; {
  …
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">AmbiguousRepository</code> and <code class="notranslate">AmbiguousUserRepository</code> extend only <code class="notranslate">Repository</code> and <code class="notranslate">CrudRepository</code> in their type hierarchy. While this is perfectly fine when using a unique Spring Data module, multiple modules cannot distinguish to which particular Spring Data these repositories should be bound.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses domain classes with annotations:</p>
</div>
<div id="repositories.multiple-modules.annotations" class="exampleblock">
<div class="title">
Example 13. Repository definitions using domain classes with annotations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, Long&gt; {
 …
}

@Entity
class Person {
  …
}

interface UserRepository extends Repository&lt;User, Long&gt; {
 …
}

@Document
class User {
  …
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">PersonRepository</code> references <code class="notranslate">Person</code>, which is annotated with the JPA <code class="notranslate">@Entity</code> annotation, so this repository clearly belongs to Spring Data JPA. <code class="notranslate">UserRepository</code> references <code class="notranslate">User</code>, which is annotated with Spring Data MongoDB’s <code class="notranslate">@Document</code> annotation.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following bad example shows a repository that uses domain classes with mixed annotations:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 14. Repository definitions using domain classes with mixed annotations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface JpaPersonRepository extends Repository&lt;Person, Long&gt; {
 …
}

interface MongoDBPersonRepository extends Repository&lt;Person, Long&gt; {
 …
}

@Entity
@Document
class Person {
  …
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example shows a domain class using both JPA and Spring Data MongoDB annotations. It defines two repositories, <code class="notranslate">JpaPersonRepository</code> and <code class="notranslate">MongoDBPersonRepository</code>. One is intended for JPA and the other for MongoDB usage. Spring Data is no longer able to tell the repositories apart, which leads to undefined behavior.</p>
</div>
</div>
</div>
<div class="paragraph">
<p><a href="#repositories.multiple-modules.types">Repository type details</a> and <a href="#repositories.multiple-modules.annotations">distinguishing domain class annotations</a> are used for strict repository configuration to identify repository candidates for a particular Spring Data module. Using multiple persistence technology-specific annotations on the same domain type is possible and enables reuse of domain types across multiple persistence technologies. However, Spring Data can then no longer determine a unique module with which to bind the repository.</p>
</div>
<div class="paragraph">
<p>The last way to distinguish repositories is by scoping repository base packages. Base packages define the starting points for scanning for repository interface definitions, which implies having repository definitions located in the appropriate packages. By default, annotation-driven configuration uses the package of the configuration class. The <a href="#repositories.create-instances.spring">base package in XML-based configuration</a> is mandatory.</p>
</div>
<div class="paragraph">
<p>The following example shows annotation-driven configuration of base packages:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 15. Annotation-driven configuration of base packages
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
interface Configuration { }</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.query-methods.details"><a class="anchor" href="#repositories.query-methods.details"></a>4.4. Defining Query Methods</h3>
<div class="paragraph">
<p>The repository proxy has two ways to derive a store-specific query from the method name:</p>
</div>
<div class="ulist">
<ul>
<li> <p>By deriving the query from the method name directly.</p> </li>
<li> <p>By using a manually defined query.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Available options depend on the actual store. However, there must be a strategy that decides what actual query is created. The next section describes the available options.</p>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-lookup-strategies"><a class="anchor" href="#repositories.query-methods.query-lookup-strategies"></a>4.4.1. Query Lookup Strategies</h4>
<div class="paragraph">
<p>The following strategies are available for the repository infrastructure to resolve the query. With XML configuration, you can configure the strategy at the namespace through the <code class="notranslate">query-lookup-strategy</code> attribute. For Java configuration, you can use the <code class="notranslate">queryLookupStrategy</code> attribute of the <code class="notranslate">Enable${store}Repositories</code> annotation. Some strategies may not be supported for particular datastores.</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">CREATE</code> attempts to construct a store-specific query from the query method name. The general approach is to remove a given set of well known prefixes from the method name and parse the rest of the method. You can read more about query construction in “<a href="#repositories.query-methods.query-creation">Query Creation</a>”.</p> </li>
<li> <p><code class="notranslate">USE_DECLARED_QUERY</code> tries to find a declared query and throws an exception if cannot find one. The query can be defined by an annotation somewhere or declared by other means. Consult the documentation of the specific store to find available options for that store. If the repository infrastructure does not find a declared query for the method at bootstrap time, it fails.</p> </li>
<li> <p><code class="notranslate">CREATE_IF_NOT_FOUND</code> (default) combines <code class="notranslate">CREATE</code> and <code class="notranslate">USE_DECLARED_QUERY</code>. It looks up a declared query first, and, if no declared query is found, it creates a custom method name-based query. This is the default lookup strategy and, thus, is used if you do not configure anything explicitly. It allows quick query definition by method names but also custom-tuning of these queries by introducing declared queries as needed.</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-creation"><a class="anchor" href="#repositories.query-methods.query-creation"></a>4.4.2. Query Creation</h4>
<div class="paragraph">
<p>The query builder mechanism built into Spring Data repository infrastructure is useful for building constraining queries over entities of the repository. The mechanism strips the prefixes <code class="notranslate">find…By</code>, <code class="notranslate">read…By</code>, <code class="notranslate">query…By</code>, <code class="notranslate">count…By</code>, and <code class="notranslate">get…By</code> from the method and starts parsing the rest of it. The introducing clause can contain further expressions, such as a <code class="notranslate">Distinct</code> to set a distinct flag on the query to be created. However, the first <code class="notranslate">By</code> acts as delimiter to indicate the start of the actual criteria. At a very basic level, you can define conditions on entity properties and concatenate them with <code class="notranslate">And</code> and <code class="notranslate">Or</code>. The following example shows how to create a number of queries:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 16. Query creation from method names
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;User, Long&gt; {

  List&lt;Person&gt; findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // Enables the distinct flag for the query
  List&lt;Person&gt; findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List&lt;Person&gt; findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // Enabling ignoring case for an individual property
  List&lt;Person&gt; findByLastnameIgnoreCase(String lastname);
  // Enabling ignoring case for all suitable properties
  List&lt;Person&gt; findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // Enabling static ORDER BY for a query
  List&lt;Person&gt; findByLastnameOrderByFirstnameAsc(String lastname);
  List&lt;Person&gt; findByLastnameOrderByFirstnameDesc(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The actual result of parsing the method depends on the persistence store for which you create the query. However, there are some general things to notice:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The expressions are usually property traversals combined with operators that can be concatenated. You can combine property expressions with <code class="notranslate">AND</code> and <code class="notranslate">OR</code>. You also get support for operators such as <code class="notranslate">Between</code>, <code class="notranslate">LessThan</code>, <code class="notranslate">GreaterThan</code>, and <code class="notranslate">Like</code> for the property expressions. The supported operators can vary by datastore, so consult the appropriate part of your reference documentation.</p> </li>
<li> <p>The method parser supports setting an <code class="notranslate">IgnoreCase</code> flag for individual properties (for example, <code class="notranslate">findByLastnameIgnoreCase(…)</code>) or for all properties of a type that supports ignoring case (usually <code class="notranslate">String</code> instances — for example, <code class="notranslate">findByLastnameAndFirstnameAllIgnoreCase(…)</code>). Whether ignoring cases is supported may vary by store, so consult the relevant sections in the reference documentation for the store-specific query method.</p> </li>
<li> <p>You can apply static ordering by appending an <code class="notranslate">OrderBy</code> clause to the query method that references a property and by providing a sorting direction (<code class="notranslate">Asc</code> or <code class="notranslate">Desc</code>). To create a query method that supports dynamic sorting, see “<a href="#repositories.special-parameters">Special parameter handling</a>”.</p> </li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-methods.query-property-expressions"><a class="anchor" href="#repositories.query-methods.query-property-expressions"></a>4.4.3. Property Expressions</h4>
<div class="paragraph">
<p>Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time, you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties. Consider the following method signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">List&lt;Person&gt; findByAddressZipCode(ZipCode zipCode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assume a <code class="notranslate">Person</code> has an <code class="notranslate">Address</code> with a <code class="notranslate">ZipCode</code>. In that case, the method creates the property traversal <code class="notranslate">x.address.zipCode</code>. The resolution algorithm starts by interpreting the entire part (<code class="notranslate">AddressZipCode</code>) as the property and checks the domain class for a property with that name (uncapitalized). If the algorithm succeeds, it uses that property. If not, the algorithm splits up the source at the camel case parts from the right side into a head and a tail and tries to find the corresponding property — in our example, <code class="notranslate">AddressZip</code> and <code class="notranslate">Code</code>. If the algorithm finds a property with that head, it takes the tail and continues building the tree down from there, splitting the tail up in the way just described. If the first split does not match, the algorithm moves the split point to the left (<code class="notranslate">Address</code>, <code class="notranslate">ZipCode</code>) and continues.</p>
</div>
<div class="paragraph">
<p>Although this should work for most cases, it is possible for the algorithm to select the wrong property. Suppose the <code class="notranslate">Person</code> class has an <code class="notranslate">addressZip</code> property as well. The algorithm would match in the first split round already, choose the wrong property, and fail (as the type of <code class="notranslate">addressZip</code> probably has no <code class="notranslate">code</code> property).</p>
</div>
<div class="paragraph">
<p>To resolve this ambiguity you can use <code class="notranslate">_</code> inside your method name to manually define traversal points. So our method name would be as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">List&lt;Person&gt; findByAddress_ZipCode(ZipCode zipCode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead).</p>
</div>
</div>
<div class="sect3">
<h4 id="repositories.special-parameters"><a class="anchor" href="#repositories.special-parameters"></a>4.4.4. Special parameter handling</h4>
<div class="paragraph">
<p>To handle parameters in your query, define method parameters as already seen in the preceding examples. Besides that, the infrastructure recognizes certain specific types like <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code>, to apply pagination and sorting to your queries dynamically. The following example demonstrates these features:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 17. Using
<code class="notranslate">Pageable</code>,
<code class="notranslate">Slice</code>, and
<code class="notranslate">Sort</code> in query methods
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">Page&lt;User&gt; findByLastname(String lastname, Pageable pageable);

Slice&lt;User&gt; findByLastname(String lastname, Pageable pageable);

List&lt;User&gt; findByLastname(String lastname, Sort sort);

List&lt;User&gt; findByLastname(String lastname, Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The first method lets you pass an <code class="notranslate">org.springframework.data.domain.Pageable</code> instance to the query method to dynamically add paging to your statically defined query. A <code class="notranslate">Page</code> knows about the total number of elements and pages available. It does so by the infrastructure triggering a count query to calculate the overall number. As this might be expensive (depending on the store used), you can instead return a <code class="notranslate">Slice</code>. A <code class="notranslate">Slice</code> only knows about whether a next <code class="notranslate">Slice</code> is available, which might be sufficient when walking through a larger result set.</p>
</div>
<div class="paragraph">
<p>Sorting options are handled through the <code class="notranslate">Pageable</code> instance, too. If you only need sorting, add an <code class="notranslate">org.springframework.data.domain.Sort</code> parameter to your method. As you can see, returning a <code class="notranslate">List</code> is also possible. In this case, the additional metadata required to build the actual <code class="notranslate">Page</code> instance is not created (which, in turn, means that the additional count query that would have been necessary is not issued). Rather, it restricts the query to look up only the given range of entities.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> To find out how many pages you get for an entire query, you have to trigger an additional count query. By default, this query is derived from the query you actually trigger. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.limit-query-result"><a class="anchor" href="#repositories.limit-query-result"></a>4.4.5. Limiting Query Results</h4>
<div class="paragraph">
<p>The results of query methods can be limited by using the <code class="notranslate">first</code> or <code class="notranslate">top</code> keywords, which can be used interchangeably. An optional numeric value can be appended to <code class="notranslate">top</code> or <code class="notranslate">first</code> to specify the maximum result size to be returned. If the number is left out, a result size of 1 is assumed. The following example shows how to limit the query size:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 18. Limiting the result size of a query with
<code class="notranslate">Top</code> and
<code class="notranslate">First</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">User findFirstByOrderByLastnameAsc();

User findTopByOrderByAgeDesc();

Page&lt;User&gt; queryFirst10ByLastname(String lastname, Pageable pageable);

Slice&lt;User&gt; findTop3ByLastname(String lastname, Pageable pageable);

List&lt;User&gt; findFirst10ByLastname(String lastname, Sort sort);

List&lt;User&gt; findTop10ByLastname(String lastname, Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The limiting expressions also support the <code class="notranslate">Distinct</code> keyword. Also, for the queries limiting the result set to one instance, wrapping the result into with the <code class="notranslate">Optional</code> keyword is supported.</p>
</div>
<div class="paragraph">
<p>If pagination or slicing is applied to a limiting query pagination (and the calculation of the number of pages available), it is applied within the limited result.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Limiting the results in combination with dynamic sorting by using a <code class="notranslate">Sort</code> parameter lets you express query methods for the 'K' smallest as well as for the 'K' biggest elements. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-streaming"><a class="anchor" href="#repositories.query-streaming"></a>4.4.6. Streaming query results</h4>
<div class="paragraph">
<p>The results of query methods can be processed incrementally by using a Java 8 <code class="notranslate">Stream&lt;T&gt;</code> as return type. Instead of wrapping the query results in a <code class="notranslate">Stream</code> data store-specific methods are used to perform the streaming, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 19. Stream the result of a query with Java 8
<code class="notranslate">Stream&lt;T&gt;</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Query("select u from User u")
Stream&lt;User&gt; findAllByCustomQueryAndStream();

Stream&lt;User&gt; readAllByFirstnameNotNull();

@Query("select u from User u")
Stream&lt;User&gt; streamAllPaged(Pageable pageable);</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> A <code class="notranslate">Stream</code> potentially wraps underlying data store-specific resources and must, therefore, be closed after usage. You can either manually close the <code class="notranslate">Stream</code> by using the <code class="notranslate">close()</code> method or by using a Java 7 <code class="notranslate">try-with-resources</code> block, as shown in the following example: </td>
</tr>
</tbody>
</table>
</div>
<div class="exampleblock">
<div class="title">
Example 20. Working with a
<code class="notranslate">Stream&lt;T&gt;</code> result in a try-with-resources block
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">try (Stream&lt;User&gt; stream = repository.findAllByCustomQueryAndStream()) {
  stream.forEach(…);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Not all Spring Data modules currently support <code class="notranslate">Stream&lt;T&gt;</code> as a return type. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.query-async"><a class="anchor" href="#repositories.query-async"></a>4.4.7. Async query results</h4>
<div class="paragraph">
<p>Repository queries can be run asynchronously by using <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/integration.html#scheduling');" target="_blank" rel="noopener noreferrer">Spring’s asynchronous method execution capability <i class="fa fa-external-link"></i></a>. This means the method returns immediately upon invocation while the actual query execution occurs in a task that has been submitted to a Spring <code class="notranslate">TaskExecutor</code>. Asynchronous query execution is different from reactive query execution and should not be mixed. Refer to store-specific documentation for more details on reactive support. The following example shows a number of asynchronous queries:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Async
Future&lt;User&gt; findByFirstname(String firstname);               <i class="conum" data-value="1"></i><b>(1)</b>

@Async
CompletableFuture&lt;User&gt; findOneByFirstname(String firstname); <i class="conum" data-value="2"></i><b>(2)</b>

@Async
ListenableFuture&lt;User&gt; findOneByLastname(String lastname);    <i class="conum" data-value="3"></i><b>(3)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Use <code class="notranslate">java.util.concurrent.Future</code> as the return type.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Use a Java 8 <code class="notranslate">java.util.concurrent.CompletableFuture</code> as the return type.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Use a <code class="notranslate">org.springframework.util.concurrent.ListenableFuture</code> as the return type.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.create-instances"><a class="anchor" href="#repositories.create-instances"></a>4.5. Creating Repository Instances</h3>
<div class="paragraph">
<p>In this section, you create instances and bean definitions for the defined repository interfaces. One way to do so is by using the Spring namespace that is shipped with each Spring Data module that supports the repository mechanism, although we generally recommend using Java configuration.</p>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.spring"><a class="anchor" href="#repositories.create-instances.spring"></a>4.5.1. XML configuration</h4>
<div class="paragraph">
<p>Each Spring Data module includes a <code class="notranslate">repositories</code> element that lets you define a base package that Spring scans for you, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 21. Enabling Spring Data repositories via XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.springframework.org/schema/data/jpa"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

  &lt;repositories base-package="com.acme.repositories" /&gt;

&lt;/beans:beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, Spring is instructed to scan <code class="notranslate">com.acme.repositories</code> and all its sub-packages for interfaces extending <code class="notranslate">Repository</code> or one of its sub-interfaces. For each interface found, the infrastructure registers the persistence technology-specific <code class="notranslate">FactoryBean</code> to create the appropriate proxies that handle invocations of the query methods. Each bean is registered under a bean name that is derived from the interface name, so an interface of <code class="notranslate">UserRepository</code> would be registered under <code class="notranslate">userRepository</code>. The <code class="notranslate">base-package</code> attribute allows wildcards so that you can define a pattern of scanned packages.</p>
</div>
<div class="sect4">
<h5 id="_using_filters"><a class="anchor" href="#_using_filters"></a>Using filters</h5>
<div class="paragraph">
<p>By default, the infrastructure picks up every interface extending the persistence technology-specific <code class="notranslate">Repository</code> sub-interface located under the configured base package and creates a bean instance for it. However, you might want more fine-grained control over which interfaces have bean instances created for them. To do so, use <code class="notranslate">&lt;include-filter /&gt;</code> and <code class="notranslate">&lt;exclude-filter /&gt;</code> elements inside the <code class="notranslate">&lt;repositories /&gt;</code> element. The semantics are exactly equivalent to the elements in Spring’s context namespace. For details, see the <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#beans-scanning-filters');" target="_blank" rel="noopener noreferrer">Spring reference documentation <i class="fa fa-external-link"></i></a> for these elements.</p>
</div>
<div class="paragraph">
<p>For example, to exclude certain interfaces from instantiation as repository beans, you could use the following configuration:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 22. Using exclude-filter element
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repositories"&gt;
  &lt;context:exclude-filter type="regex" expression=".*SomeRepository" /&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding example excludes all interfaces ending in <code class="notranslate">SomeRepository</code> from being instantiated.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.java-config"><a class="anchor" href="#repositories.create-instances.java-config"></a>4.5.2. JavaConfig</h4>
<div class="paragraph">
<p>The repository infrastructure can also be triggered by using a store-specific <code class="notranslate">@Enable${store}Repositories</code> annotation on a JavaConfig class. For an introduction into Java-based configuration of the Spring container, see <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#beans-java');" target="_blank" rel="noopener noreferrer">JavaConfig in the Spring reference documentation <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>A sample configuration to enable Spring Data repositories resembles the following:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 23. Sample annotation based repository configuration
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {

  @Bean
  EntityManagerFactory entityManagerFactory() {
    // …
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The preceding example uses the JPA-specific annotation, which you would change according to the store module you actually use. The same applies to the definition of the <code class="notranslate">EntityManagerFactory</code> bean. See the sections covering the store-specific configuration. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="repositories.create-instances.standalone"><a class="anchor" href="#repositories.create-instances.standalone"></a>4.5.3. Standalone usage</h4>
<div class="paragraph">
<p>You can also use the repository infrastructure outside of a Spring container — for example, in CDI environments. You still need some Spring libraries in your classpath, but, generally, you can set up repositories programmatically as well. The Spring Data modules that provide repository support ship a persistence technology-specific <code class="notranslate">RepositoryFactory</code> that you can use as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 24. Standalone usage of repository factory
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">RepositoryFactorySupport factory = … // Instantiate factory here
UserRepository repository = factory.getRepository(UserRepository.class);</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="repositories.custom-implementations"><a class="anchor" href="#repositories.custom-implementations"></a>4.6. Custom Implementations for Spring Data Repositories</h3>
<div class="paragraph">
<p>This section covers repository customization and how fragments form a composite repository.</p>
</div>
<div class="paragraph">
<p>When a query method requires a different behavior or cannot be implemented by query derivation, then it is necessary to provide a custom implementation. Spring Data repositories let you provide custom repository code and integrate it with generic CRUD abstraction and query method functionality.</p>
</div>
<div class="sect3">
<h4 id="repositories.single-repository-behavior"><a class="anchor" href="#repositories.single-repository-behavior"></a>4.6.1. Customizing Individual Repositories</h4>
<div class="paragraph">
<p>To enrich a repository with custom functionality, you must first define a fragment interface and an implementation for the custom functionality, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 25. Interface for custom repository functionality
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface CustomizedUserRepository {
  void someCustomMethod(User user);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Then you can let your repository interface additionally extend from the fragment interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 26. Implementation of custom repository functionality
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  public void someCustomMethod(User user) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The most important part of the class name that corresponds to the fragment interface is the <code class="notranslate">Impl</code> postfix. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The implementation itself does not depend on Spring Data and can be a regular Spring bean. Consequently, you can use standard dependency injection behavior to inject references to other beans (such as a <code class="notranslate">JdbcTemplate</code>), take part in aspects, and so on.</p>
</div>
<div class="paragraph">
<p>You can let your repository interface extend the fragment interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 27. Changes to your repository interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, CustomizedUserRepository {

  // Declare query methods here
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Extending the fragment interface with your repository interface combines the CRUD and custom functionality and makes it available to clients.</p>
</div>
<div class="paragraph">
<p>Spring Data repositories are implemented by using fragments that form a repository composition. Fragments are the base repository, functional aspects (such as <a href="#core.extensions.querydsl">QueryDsl</a>), and custom interfaces along with their implementation. Each time you add an interface to your repository interface, you enhance the composition by adding a fragment. The base repository and repository aspect implementations are provided by each Spring Data module.</p>
</div>
<div class="paragraph">
<p>The following example shows custom interfaces and their implementations:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 28. Fragments with their implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface HumanRepository {
  void someHumanMethod(User user);
}

class HumanRepositoryImpl implements HumanRepository {

  public void someHumanMethod(User user) {
    // Your custom implementation
  }
}

interface ContactRepository {

  void someContactMethod(User user);

  User anotherContactMethod(User user);
}

class ContactRepositoryImpl implements ContactRepository {

  public void someContactMethod(User user) {
    // Your custom implementation
  }

  public User anotherContactMethod(User user) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows the interface for a custom repository that extends <code class="notranslate">CrudRepository</code>:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 29. Changes to your repository interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, HumanRepository, ContactRepository {

  // Declare query methods here
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Repositories may be composed of multiple custom implementations that are imported in the order of their declaration. Custom implementations have a higher priority than the base implementation and repository aspects. This ordering lets you override base repository and aspect methods and resolves ambiguity if two fragments contribute the same method signature. Repository fragments are not limited to use in a single repository interface. Multiple repositories may use a fragment interface, letting you reuse customizations across different repositories.</p>
</div>
<div class="paragraph">
<p>The following example shows a repository fragment and its implementation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 30. Fragments overriding
<code class="notranslate">save(…)</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface CustomizedSave&lt;T&gt; {
  &lt;S extends T&gt; S save(S entity);
}

class CustomizedSaveImpl&lt;T&gt; implements CustomizedSave&lt;T&gt; {

  public &lt;S extends T&gt; S save(S entity) {
    // Your custom implementation
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows a repository that uses the preceding repository fragment:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 31. Customized repository interfaces
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, CustomizedSave&lt;User&gt; {
}

interface PersonRepository extends CrudRepository&lt;Person, Long&gt;, CustomizedSave&lt;Person&gt; {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuration"><a class="anchor" href="#_configuration"></a>Configuration</h5>
<div class="paragraph">
<p>If you use namespace configuration, the repository infrastructure tries to autodetect custom implementation fragments by scanning for classes below the package in which it found a repository. These classes need to follow the naming convention of appending the namespace element’s <code class="notranslate">repository-impl-postfix</code> attribute to the fragment interface name. This postfix defaults to <code class="notranslate">Impl</code>. The following example shows a repository that uses the default postfix and a repository that sets a custom value for the postfix:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 32. Configuration example
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repository" /&gt;

&lt;repositories base-package="com.acme.repository" repository-impl-postfix="MyPostfix" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The first configuration in the preceding example tries to look up a class called <code class="notranslate">com.acme.repository.CustomizedUserRepositoryImpl</code> to act as a custom repository implementation. The second example tries to lookup <code class="notranslate">com.acme.repository.CustomizedUserRepositoryMyPostfix</code>.</p>
</div>
<div class="sect5">
<h6 id="repositories.single-repository-behaviour.ambiguity"><a class="anchor" href="#repositories.single-repository-behaviour.ambiguity"></a>Resolution of Ambiguity</h6>
<div class="paragraph">
<p>If multiple implementations with matching class names are found in different packages, Spring Data uses the bean names to identify which one to use.</p>
</div>
<div class="paragraph">
<p>Given the following two custom implementations for the <code class="notranslate">CustomizedUserRepository</code> shown earlier, the first implementation is used. Its bean name is <code class="notranslate">customizedUserRepositoryImpl</code>, which matches that of the fragment interface (<code class="notranslate">CustomizedUserRepository</code>) plus the postfix <code class="notranslate">Impl</code>.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 33. Resolution of amibiguous implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">package com.acme.impl.one;

class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  // Your custom implementation
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">package com.acme.impl.two;

@Component("specialCustomImpl")
class CustomizedUserRepositoryImpl implements CustomizedUserRepository {

  // Your custom implementation
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If you annotate the <code class="notranslate">UserRepository</code> interface with <code class="notranslate">@Component("specialCustom")</code>, the bean name plus <code class="notranslate">Impl</code> then matches the one defined for the repository implementation in <code class="notranslate">com.acme.impl.two</code>, and it is used instead of the first one.</p>
</div>
</div>
<div class="sect5">
<h6 id="repositories.manual-wiring"><a class="anchor" href="#repositories.manual-wiring"></a>Manual Wiring</h6>
<div class="paragraph">
<p>If your custom implementation uses annotation-based configuration and autowiring only, the preceding approach shown works well, because it is treated as any other Spring bean. If your implementation fragment bean needs special wiring, you can declare the bean and name it according to the conventions described in the <a href="#repositories.single-repository-behaviour.ambiguity">preceding section</a>. The infrastructure then refers to the manually defined bean definition by name instead of creating one itself. The following example shows how to manually wire a custom implementation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 34. Manual wiring of custom implementations
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repository" /&gt;

&lt;beans:bean id="userRepositoryImpl" class="…"&gt;
  &lt;!-- further configuration --&gt;
&lt;/beans:bean&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="repositories.customize-base-repository"><a class="anchor" href="#repositories.customize-base-repository"></a>4.6.2. Customize the Base Repository</h4>
<div class="paragraph">
<p>The approach described in the <a href="#repositories.manual-wiring">preceding section</a> requires customization of each repository interfaces when you want to customize the base repository behavior so that all repositories are affected. To instead change behavior for all repositories, you can create an implementation that extends the persistence technology-specific repository base class. This class then acts as a custom base class for the repository proxies, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 35. Custom repository base class
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class MyRepositoryImpl&lt;T, ID extends Serializable&gt;
  extends SimpleJpaRepository&lt;T, ID&gt; {

  private final EntityManager entityManager;

  MyRepositoryImpl(JpaEntityInformation entityInformation,
                          EntityManager entityManager) {
    super(entityInformation, entityManager);

    // Keep the EntityManager around to used from the newly introduced methods.
    this.entityManager = entityManager;
  }

  @Transactional
  public &lt;S extends T&gt; S save(S entity) {
    // implementation goes here
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock caution">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-caution" title="Caution"></i> </td>
<td class="content"> The class needs to have a constructor of the super class which the store-specific repository factory implementation uses. If the repository base class has multiple constructors, override the one taking an <code class="notranslate">EntityInformation</code> plus a store specific infrastructure object (such as an <code class="notranslate">EntityManager</code> or a template class). </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The final step is to make the Spring Data infrastructure aware of the customized repository base class. In Java configuration, you can do so by using the <code class="notranslate">repositoryBaseClass</code> attribute of the <code class="notranslate">@Enable${store}Repositories</code> annotation, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 36. Configuring a custom repository base class using JavaConfig
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration { … }</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>A corresponding attribute is available in the XML namespace, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 37. Configuring a custom repository base class using XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;repositories base-package="com.acme.repository"
     base-class="….MyRepositoryImpl" /&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="core.domain-events"><a class="anchor" href="#core.domain-events"></a>4.7. Publishing Events from Aggregate Roots</h3>
<div class="paragraph">
<p>Entities managed by repositories are aggregate roots. In a Domain-Driven Design application, these aggregate roots usually publish domain events. Spring Data provides an annotation called <code class="notranslate">@DomainEvents</code> that you can use on a method of your aggregate root to make that publication as easy as possible, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 38. Exposing domain events from an aggregate root
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class AnAggregateRoot {

    @DomainEvents <i class="conum" data-value="1"></i><b>(1)</b>
    Collection&lt;Object&gt; domainEvents() {
        // … return events you want to get published here
    }

    @AfterDomainEventPublication <i class="conum" data-value="2"></i><b>(2)</b>
    void callbackMethod() {
       // … potentially clean up domain events list
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The method using <code class="notranslate">@DomainEvents</code> can return either a single event instance or a collection of events. It must not take any arguments.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>After all events have been published, we have a method annotated with <code class="notranslate">@AfterDomainEventPublication</code>. It can be used to potentially clean the list of events to be published (among other uses).</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>The methods are called every time one of a Spring Data repository’s <code class="notranslate">save(…)</code> methods is called.</p>
</div>
</div>
<div class="sect2">
<h3 id="core.extensions"><a class="anchor" href="#core.extensions"></a>4.8. Spring Data Extensions</h3>
<div class="paragraph">
<p>This section documents a set of Spring Data extensions that enable Spring Data usage in a variety of contexts. Currently, most of the integration is targeted towards Spring MVC.</p>
</div>
<div class="sect3">
<h4 id="core.extensions.querydsl"><a class="anchor" href="#core.extensions.querydsl"></a>4.8.1. Querydsl Extension</h4>
<div class="paragraph">
<p><a href="javascript:window.open('http://www.querydsl.com/');" target="_blank" rel="noopener noreferrer">Querydsl <i class="fa fa-external-link"></i></a> is a framework that enables the construction of statically typed SQL-like queries through its fluent API.</p>
</div>
<div class="paragraph">
<p>Several Spring Data modules offer integration with Querydsl through <code class="notranslate">QuerydslPredicateExecutor</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 39. QuerydslPredicateExecutor interface
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface QuerydslPredicateExecutor&lt;T&gt; {

  Optional&lt;T&gt; findById(Predicate predicate);  <i class="conum" data-value="1"></i><b>(1)</b>

  Iterable&lt;T&gt; findAll(Predicate predicate);   <i class="conum" data-value="2"></i><b>(2)</b>

  long count(Predicate predicate);            <i class="conum" data-value="3"></i><b>(3)</b>

  boolean exists(Predicate predicate);        <i class="conum" data-value="4"></i><b>(4)</b>

  // … more functionality omitted.
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Finds and returns a single entity matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Finds and returns all entities matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Returns the number of entities matching the <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Returns whether an entity that matches the <code class="notranslate">Predicate</code> exists.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>To make use of Querydsl support, extend <code class="notranslate">QuerydslPredicateExecutor</code> on your repository interface, as shown in the following example</p>
</div>
<div class="exampleblock">
<div class="title">
Example 40. Querydsl integration on repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, Long&gt;, QuerydslPredicateExecutor&lt;User&gt; {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding example lets you write typesafe queries using Querydsl <code class="notranslate">Predicate</code> instances, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">Predicate predicate = user.firstname.equalsIgnoreCase("dave")
	.and(user.lastname.startsWithIgnoreCase("mathews"));

userRepository.findAll(predicate);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="core.web"><a class="anchor" href="#core.web"></a>4.8.2. Web support</h4>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> This section contains the documentation for the Spring Data web support as it is implemented in the current (and later) versions of Spring Data Commons. As the newly introduced support changes many things, we kept the documentation of the former behavior in <a href="#web.legacy">[web.legacy]</a>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Spring Data modules that support the repository programming model ship with a variety of web support. The web related components require Spring MVC JARs to be on the classpath. Some of them even provide integration with <a href="javascript:window.open('https://github.com/SpringSource/spring-hateoas');" target="_blank" rel="noopener noreferrer">Spring HATEOAS <i class="fa fa-external-link"></i></a>. In general, the integration support is enabled by using the <code class="notranslate">@EnableSpringDataWebSupport</code> annotation in your JavaConfig configuration class, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 41. Enabling Spring Data web support
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The <code class="notranslate">@EnableSpringDataWebSupport</code> annotation registers a few components we will discuss in a bit. It will also detect Spring HATEOAS on the classpath and register integration components for it as well if present.</p>
</div>
<div class="paragraph">
<p>Alternatively, if you use XML configuration, register either <code class="notranslate">SpringDataWebConfiguration</code> or <code class="notranslate">HateoasAwareSpringDataWebConfiguration</code> as Spring beans, as shown in the following example (for <code class="notranslate">SpringDataWebConfiguration</code>):</p>
</div>
<div class="exampleblock">
<div class="title">
Example 42. Enabling Spring Data web support in XML
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;bean class="org.springframework.data.web.config.SpringDataWebConfiguration" /&gt;

&lt;!-- If you use Spring HATEOAS, register this one *instead* of the former --&gt;
&lt;bean class="org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration" /&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="core.web.basic"><a class="anchor" href="#core.web.basic"></a>Basic Web Support</h5>
<div class="paragraph">
<p>The configuration shown in the <a href="#core.web">previous section</a> registers a few basic components:</p>
</div>
<div class="ulist">
<ul>
<li> <p>A <a href="#core.web.basic.domain-class-converter"><code class="notranslate">DomainClassConverter</code></a> to let Spring MVC resolve instances of repository-managed domain classes from request parameters or path variables.</p> </li>
<li> <p><a href="#core.web.basic.paging-and-sorting"><code class="notranslate">HandlerMethodArgumentResolver</code></a> implementations to let Spring MVC resolve <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code> instances from request parameters.</p> </li>
</ul>
</div>
<div class="sect5">
<h6 id="core.web.basic.domain-class-converter"><a class="anchor" href="#core.web.basic.domain-class-converter"></a><code class="notranslate">DomainClassConverter</code></h6>
<div class="paragraph">
<p>The <code class="notranslate">DomainClassConverter</code> lets you use domain types in your Spring MVC controller method signatures directly, so that you need not manually lookup the instances through the repository, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 43. A Spring MVC controller using domain types in method signatures
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
@RequestMapping("/users")
class UserController {

  @RequestMapping("/{id}")
  String showUserForm(@PathVariable("id") User user, Model model) {

    model.addAttribute("user", user);
    return "userForm";
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>As you can see, the method receives a <code class="notranslate">User</code> instance directly, and no further lookup is necessary. The instance can be resolved by letting Spring MVC convert the path variable into the <code class="notranslate">id</code> type of the domain class first and eventually access the instance through calling <code class="notranslate">findById(…)</code> on the repository instance registered for the domain type.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Currently, the repository has to implement <code class="notranslate">CrudRepository</code> to be eligible to be discovered for conversion. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect5">
<h6 id="core.web.basic.paging-and-sorting"><a class="anchor" href="#core.web.basic.paging-and-sorting"></a>HandlerMethodArgumentResolvers for Pageable and Sort</h6>
<div class="paragraph">
<p>The configuration snippet shown in the <a href="#core.web.basic.domain-class-converter">previous section</a> also registers a <code class="notranslate">PageableHandlerMethodArgumentResolver</code> as well as an instance of <code class="notranslate">SortHandlerMethodArgumentResolver</code>. The registration enables <code class="notranslate">Pageable</code> and <code class="notranslate">Sort</code> as valid controller method arguments, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 44. Using Pageable as controller method argument
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
@RequestMapping("/users")
class UserController {

  private final UserRepository repository;

  UserController(UserRepository repository) {
    this.repository = repository;
  }

  @RequestMapping
  String showUsers(Model model, Pageable pageable) {

    model.addAttribute("users", repository.findAll(pageable));
    return "users";
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding method signature causes Spring MVC try to derive a <code class="notranslate">Pageable</code> instance from the request parameters by using the following default configuration:</p>
</div>
<table class="tableblock frame-all grid-all fit-content">
<caption class="title">
Table 1. Request parameters evaluated for
<code class="notranslate">Pageable</code> instances
</caption>
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">page</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Page you want to retrieve. 0-indexed and defaults to 0.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">size</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Size of the page you want to retrieve. Defaults to 20.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">sort</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Properties that should be sorted by in the format <code class="notranslate">property,property(,ASC|DESC)</code>. Default sort direction is ascending. Use multiple <code class="notranslate">sort</code> parameters if you want to switch directions — for example, <code class="notranslate">?sort=firstname&amp;sort=lastname,asc</code>.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>To customize this behavior, register a bean implementing the <code class="notranslate">PageableHandlerMethodArgumentResolverCustomizer</code> interface or the <code class="notranslate">SortHandlerMethodArgumentResolverCustomizer</code> interface, respectively. Its <code class="notranslate">customize()</code> method gets called, letting you change settings, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Bean SortHandlerMethodArgumentResolverCustomizer sortCustomizer() {
    return s -&gt; s.setPropertyDelimiter("&lt;--&gt;");
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If setting the properties of an existing <code class="notranslate">MethodArgumentResolver</code> is not sufficient for your purpose, extend either <code class="notranslate">SpringDataWebConfiguration</code> or the HATEOAS-enabled equivalent, override the <code class="notranslate">pageableResolver()</code> or <code class="notranslate">sortResolver()</code> methods, and import your customized configuration file instead of using the <code class="notranslate">@Enable</code> annotation.</p>
</div>
<div class="paragraph">
<p>If you need multiple <code class="notranslate">Pageable</code> or <code class="notranslate">Sort</code> instances to be resolved from the request (for multiple tables, for example), you can use Spring’s <code class="notranslate">@Qualifier</code> annotation to distinguish one from another. The request parameters then have to be prefixed with <code class="notranslate">${qualifier}_</code>. The followig example shows the resulting method signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">String showUsers(Model model,
      @Qualifier("thing1") Pageable first,
      @Qualifier("thing2") Pageable second) { … }</code></pre>
</div>
</div>
<div class="paragraph">
<p>you have to populate <code class="notranslate">thing1_page</code> and <code class="notranslate">thing2_page</code> and so on.</p>
</div>
<div class="paragraph">
<p>The default <code class="notranslate">Pageable</code> passed into the method is equivalent to a <code class="notranslate">PageRequest.of(0, 20)</code> but can be customized by using the <code class="notranslate">@PageableDefault</code> annotation on the <code class="notranslate">Pageable</code> parameter.</p>
</div>
</div>
</div>
<div class="sect4">
<h5 id="core.web.pageables"><a class="anchor" href="#core.web.pageables"></a>Hypermedia Support for Pageables</h5>
<div class="paragraph">
<p>Spring HATEOAS ships with a representation model class (<code class="notranslate">PagedResources</code>) that allows enriching the content of a <code class="notranslate">Page</code> instance with the necessary <code class="notranslate">Page</code> metadata as well as links to let the clients easily navigate the pages. The conversion of a Page to a <code class="notranslate">PagedResources</code> is done by an implementation of the Spring HATEOAS <code class="notranslate">ResourceAssembler</code> interface, called the <code class="notranslate">PagedResourcesAssembler</code>. The following example shows how to use a <code class="notranslate">PagedResourcesAssembler</code> as a controller method argument:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 45. Using a PagedResourcesAssembler as controller method argument
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
class PersonController {

  @Autowired PersonRepository repository;

  @RequestMapping(value = "/persons", method = RequestMethod.GET)
  HttpEntity&lt;PagedResources&lt;Person&gt;&gt; persons(Pageable pageable,
    PagedResourcesAssembler assembler) {

    Page&lt;Person&gt; persons = repository.findAll(pageable);
    return new ResponseEntity&lt;&gt;(assembler.toResources(persons), HttpStatus.OK);
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Enabling the configuration as shown in the preceding example lets the <code class="notranslate">PagedResourcesAssembler</code> be used as a controller method argument. Calling <code class="notranslate">toResources(…)</code> on it has the following effects:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The content of the <code class="notranslate">Page</code> becomes the content of the <code class="notranslate">PagedResources</code> instance.</p> </li>
<li> <p>The <code class="notranslate">PagedResources</code> object gets a <code class="notranslate">PageMetadata</code> instance attached, and it is populated with information from the <code class="notranslate">Page</code> and the underlying <code class="notranslate">PageRequest</code>.</p> </li>
<li> <p>The <code class="notranslate">PagedResources</code> may get <code class="notranslate">prev</code> and <code class="notranslate">next</code> links attached, depending on the page’s state. The links point to the URI to which the method maps. The pagination parameters added to the method match the setup of the <code class="notranslate">PageableHandlerMethodArgumentResolver</code> to make sure the links can be resolved later.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Assume we have 30 Person instances in the database. You can now trigger a request (<code class="notranslate">GET <a href="javascript:window.open('http://localhost:8080/persons');" class="bare" target="_blank" rel="noopener noreferrer">http://localhost:8080/persons <i class="fa fa-external-link"></i></a></code>) and see output similar to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-javascript" data-lang="javascript">{ "links" : [ { "rel" : "next",
                "href" : "http://localhost:8080/persons?page=1&amp;size=20 }
  ],
  "content" : [
     … // 20 Person instances rendered here
  ],
  "pageMetadata" : {
    "size" : 20,
    "totalElements" : 30,
    "totalPages" : 2,
    "number" : 0
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You see that the assembler produced the correct URI and also picked up the default configuration to resolve the parameters into a <code class="notranslate">Pageable</code> for an upcoming request. This means that, if you change that configuration, the links automatically adhere to the change. By default, the assembler points to the controller method it was invoked in, but that can be customized by handing in a custom <code class="notranslate">Link</code> to be used as base to build the pagination links, which overloads the <code class="notranslate">PagedResourcesAssembler.toResource(…)</code> method.</p>
</div>
</div>
<div class="sect4">
<h5 id="core.web.binding"><a class="anchor" href="#core.web.binding"></a>Web Databinding Support</h5>
<div class="paragraph">
<p>Spring Data projections (described in <a href="#projections">Projections</a>) can be used to bind incoming request payloads by either using <a href="javascript:window.open('http://goessner.net/articles/JsonPath/');" target="_blank" rel="noopener noreferrer">JSONPath <i class="fa fa-external-link"></i></a> expressions (requires <a href="javascript:window.open('https://github.com/json-path/JsonPath');" target="_blank" rel="noopener noreferrer">Jayway JsonPath <i class="fa fa-external-link"></i></a> or <a href="javascript:window.open('https://www.w3.org/TR/xpath-31/');" target="_blank" rel="noopener noreferrer">XPath <i class="fa fa-external-link"></i></a> expressions (requires <a href="javascript:window.open('https://xmlbeam.org/');" target="_blank" rel="noopener noreferrer">XmlBeam <i class="fa fa-external-link"></i></a>), as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 46. HTTP payload binding using JSONPath or XPath expressions
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@ProjectedPayload
public interface UserPayload {

  @XBRead("//firstname")
  @JsonPath("$..firstname")
  String getFirstname();

  @XBRead("/lastname")
  @JsonPath({ "$.lastname", "$.user.lastname" })
  String getLastname();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The type shown in the preceding example can be used as a Spring MVC handler method argument or by using <code class="notranslate">ParameterizedTypeReference</code> on one of <code class="notranslate">RestTemplate</code>'s methods. The preceding method declarations would try to find <code class="notranslate">firstname</code> anywhere in the given document. The <code class="notranslate">lastname</code> XML lookup is performed on the top-level of the incoming document. The JSON variant of that tries a top-level <code class="notranslate">lastname</code> first but also tries <code class="notranslate">lastname</code> nested in a <code class="notranslate">user</code> sub-document if the former does not return a value. That way, changes in the structure of the source document can be mitigated easily without having clients calling the exposed methods (usually a drawback of class-based payload binding).</p>
</div>
<div class="paragraph">
<p>Nested projections are supported as described in <a href="#projections">Projections</a>. If the method returns a complex, non-interface type, a Jackson <code class="notranslate">ObjectMapper</code> is used to map the final value.</p>
</div>
<div class="paragraph">
<p>For Spring MVC, the necessary converters are registered automatically as soon as <code class="notranslate">@EnableSpringDataWebSupport</code> is active and the required dependencies are available on the classpath. For usage with <code class="notranslate">RestTemplate</code>, register a <code class="notranslate">ProjectingJackson2HttpMessageConverter</code> (JSON) or <code class="notranslate">XmlBeamHttpMessageConverter</code> manually.</p>
</div>
<div class="paragraph">
<p>For more information, see the <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples/tree/master/web/projection');" target="_blank" rel="noopener noreferrer">web projection example <i class="fa fa-external-link"></i></a> in the canonical <a href="javascript:window.open('https://github.com/spring-projects/spring-data-examples');" target="_blank" rel="noopener noreferrer">Spring Data Examples repository <i class="fa fa-external-link"></i></a>.</p>
</div>
</div>
<div class="sect4">
<h5 id="core.web.type-safe"><a class="anchor" href="#core.web.type-safe"></a>Querydsl Web Support</h5>
<div class="paragraph">
<p>For those stores having <a href="javascript:window.open('http://www.querydsl.com/');" target="_blank" rel="noopener noreferrer">QueryDSL <i class="fa fa-external-link"></i></a> integration, it is possible to derive queries from the attributes contained in a <code class="notranslate">Request</code> query string.</p>
</div>
<div class="paragraph">
<p>Consider the following query string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-text" data-lang="text">?firstname=Dave&amp;lastname=Matthews</code></pre>
</div>
</div>
<div class="paragraph">
<p>Given the <code class="notranslate">User</code> object from previous examples, a query string can be resolved to the following value by using the <code class="notranslate">QuerydslPredicateArgumentResolver</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-text" data-lang="text">QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The feature is automatically enabled, along with <code class="notranslate">@EnableSpringDataWebSupport</code>, when Querydsl is found on the classpath. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Adding a <code class="notranslate">@QuerydslPredicate</code> to the method signature provides a ready-to-use <code class="notranslate">Predicate</code>, which can be run by using the <code class="notranslate">QuerydslPredicateExecutor</code>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td>
<td class="content"> Type information is typically resolved from the method’s return type. Since that information does not necessarily match the domain type, it might be a good idea to use the <code class="notranslate">root</code> attribute of <code class="notranslate">QuerydslPredicate</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The following exampe shows how to use <code class="notranslate">@QuerydslPredicate</code> in a method signature:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Controller
class UserController {

  @Autowired UserRepository repository;

  @RequestMapping(value = "/", method = RequestMethod.GET)
  String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate,    <i class="conum" data-value="1"></i><b>(1)</b>
          Pageable pageable, @RequestParam MultiValueMap&lt;String, String&gt; parameters) {

    model.addAttribute("users", repository.findAll(predicate, pageable));

    return "index";
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Resolve query string arguments to matching <code class="notranslate">Predicate</code> for <code class="notranslate">User</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>The default binding is as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">Object</code> on simple properties as <code class="notranslate">eq</code>.</p> </li>
<li> <p><code class="notranslate">Object</code> on collection like properties as <code class="notranslate">contains</code>.</p> </li>
<li> <p><code class="notranslate">Collection</code> on simple properties as <code class="notranslate">in</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Those bindings can be customized through the <code class="notranslate">bindings</code> attribute of <code class="notranslate">@QuerydslPredicate</code> or by making use of Java 8 <code class="notranslate">default methods</code> and adding the <code class="notranslate">QuerydslBinderCustomizer</code> method to the repository interface.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends CrudRepository&lt;User, String&gt;,
                                 QuerydslPredicateExecutor&lt;User&gt;,                <i class="conum" data-value="1"></i><b>(1)</b>
                                 QuerydslBinderCustomizer&lt;QUser&gt; {               <i class="conum" data-value="2"></i><b>(2)</b>

  @Override
  default void customize(QuerydslBindings bindings, QUser user) {

    bindings.bind(user.username).first((path, value) -&gt; path.contains(value))    <i class="conum" data-value="3"></i><b>(3)</b>
    bindings.bind(String.class)
      .first((StringPath path, String value) -&gt; path.containsIgnoreCase(value)); <i class="conum" data-value="4"></i><b>(4)</b>
    bindings.excluding(user.password);                                           <i class="conum" data-value="5"></i><b>(5)</b>
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td><code class="notranslate">QuerydslPredicateExecutor</code> provides access to specific finder methods for <code class="notranslate">Predicate</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td><code class="notranslate">QuerydslBinderCustomizer</code> defined on the repository interface is automatically picked up and shortcuts <code class="notranslate">@QuerydslPredicate(bindings=…)</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Define the binding for the <code class="notranslate">username</code> property to be a simple <code class="notranslate">contains</code> binding.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Define the default binding for <code class="notranslate">String</code> properties to be a case-insensitive <code class="notranslate">contains</code> match.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b class="notranslate">5</b></td>
<td>Exclude the <code class="notranslate">password</code> property from <code class="notranslate">Predicate</code> resolution.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="core.repository-populators"><a class="anchor" href="#core.repository-populators"></a>4.8.3. Repository Populators</h4>
<div class="paragraph">
<p>If you work with the Spring JDBC module, you are probably familiar with the support to populate a <code class="notranslate">DataSource</code> with SQL scripts. A similar abstraction is available on the repositories level, although it does not use SQL as the data definition language because it must be store-independent. Thus, the populators support XML (through Spring’s OXM abstraction) and JSON (through Jackson) to define data with which to populate the repositories.</p>
</div>
<div class="paragraph">
<p>Assume you have a file <code class="notranslate">data.json</code> with the following content:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 47. Data defined in JSON
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-javascript" data-lang="javascript">[ { "_class" : "com.acme.Person",
 "firstname" : "Dave",
  "lastname" : "Matthews" },
  { "_class" : "com.acme.Person",
 "firstname" : "Carter",
  "lastname" : "Beauford" } ]</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You can populate your repositories by using the populator elements of the repository namespace provided in Spring Data Commons. To populate the preceding data to your PersonRepository, declare a populator similar to the following:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 48. Declaring a Jackson repository populator
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:repository="http://www.springframework.org/schema/data/repository"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/repository
    http://www.springframework.org/schema/data/repository/spring-repository.xsd"&gt;

  &lt;repository:jackson2-populator locations="classpath:data.json" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding declaration causes the <code class="notranslate">data.json</code> file to be read and deserialized by a Jackson <code class="notranslate">ObjectMapper</code>.</p>
</div>
<div class="paragraph">
<p>The type to which the JSON object is unmarshalled is determined by inspecting the <code class="notranslate">_class</code> attribute of the JSON document. The infrastructure eventually selects the appropriate repository to handle the object that was deserialized.</p>
</div>
<div class="paragraph">
<p>To instead use XML to define the data the repositories should be populated with, you can use the <code class="notranslate">unmarshaller-populator</code> element. You configure it to use one of the XML marshaller options available in Spring OXM. See the <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/data-access.html#oxm');" target="_blank" rel="noopener noreferrer">Spring reference documentation <i class="fa fa-external-link"></i></a> for details. The following example shows how to unmarshal a repository populator with JAXB:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 49. Declaring an unmarshalling repository populator (using JAXB)
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:repository="http://www.springframework.org/schema/data/repository"
  xmlns:oxm="http://www.springframework.org/schema/oxm"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/repository
    http://www.springframework.org/schema/data/repository/spring-repository.xsd
    http://www.springframework.org/schema/oxm
    http://www.springframework.org/schema/oxm/spring-oxm.xsd"&gt;

  &lt;repository:unmarshaller-populator locations="classpath:data.json"
    unmarshaller-ref="unmarshaller" /&gt;

  &lt;oxm:jaxb2-marshaller contextPath="com.acme" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h2 id="reference" class="sect0"><a class="anchor" href="#reference"></a>Reference Documentation</h2>
<div class="sect1">
<h2 id="jpa.repositories"><a class="anchor" href="#jpa.repositories"></a>5. JPA Repositories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter points out the specialties for repository support for JPA. This builds on the core repository support explained in “<a href="#repositories">Working with Spring Data Repositories</a>”. Make sure you have a sound understanding of the basic concepts explained there.</p>
</div>
<div class="sect2">
<h3 id="jpa.introduction"><a class="anchor" href="#jpa.introduction"></a>5.1. Introduction</h3>
<div class="paragraph">
<p>This section describes the basics of configuring Spring Data JPA through either:</p>
</div>
<div class="ulist">
<ul>
<li> <p>“<a href="#jpa.namespace">Spring Namespace</a>” (XML configuration)</p> </li>
<li> <p>“<a href="#jpa.java-config">Annotation-based Configuration</a>” (Java configuration)</p> </li>
</ul>
</div>
<div class="sect3">
<h4 id="jpa.namespace"><a class="anchor" href="#jpa.namespace"></a>5.1.1. Spring Namespace</h4>
<div class="paragraph">
<p>The JPA module of Spring Data contains a custom namespace that allows defining repository beans. It also contains certain features and element attributes that are special to JPA. Generally, the JPA repositories can be set up by using the <code class="notranslate">repositories</code> element, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 50. Setting up JPA repositories by using the namespace
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"&gt;

  &lt;jpa:repositories base-package="com.acme.repositories" /&gt;

&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Using the <code class="notranslate">repositories</code> element looks up Spring Data repositories as described in “<a href="#repositories.create-instances">Creating Repository Instances</a>”. Beyond that, it activates persistence exception translation for all beans annotated with <code class="notranslate">@Repository</code>, to let exceptions being thrown by the JPA persistence providers be converted into Spring’s <code class="notranslate">DataAccessException</code> hierarchy.</p>
</div>
<div class="sect4">
<h5 id="_custom_namespace_attributes"><a class="anchor" href="#_custom_namespace_attributes"></a>Custom Namespace Attributes</h5>
<div class="paragraph">
<p>Beyond the default attributes of the <code class="notranslate">repositories</code> element, the JPA namespace offers additional attributes to let you gain more detailed control over the setup of the repositories:</p>
</div>
<table class="tableblock frame-all grid-all fit-content">
<caption class="title">
Table 2. Custom JPA-specific attributes of the
<code class="notranslate">repositories</code> element
</caption>
<colgroup>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">entity-manager-factory-ref</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Explicitly wire the <code class="notranslate">EntityManagerFactory</code> to be used with the repositories being detected by the <code class="notranslate">repositories</code> element. Usually used if multiple <code class="notranslate">EntityManagerFactory</code> beans are used within the application. If not configured, Spring Data automatically looks up the <code class="notranslate">EntityManagerFactory</code> bean with the name <code class="notranslate">entityManagerFactory</code> in the <code class="notranslate">ApplicationContext</code>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">transaction-manager-ref</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Explicitly wire the <code class="notranslate">PlatformTransactionManager</code> to be used with the repositories being detected by the <code class="notranslate">repositories</code> element. Usually only necessary if multiple transaction managers or <code class="notranslate">EntityManagerFactory</code> beans have been configured. Default to a single defined <code class="notranslate">PlatformTransactionManager</code> inside the current <code class="notranslate">ApplicationContext</code>.</p></td>
</tr>
</tbody>
</table>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Spring Data JPA requires a <code class="notranslate">PlatformTransactionManager</code> bean named <code class="notranslate">transactionManager</code> to be present if no explicit <code class="notranslate">transaction-manager-ref</code> is defined. </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpa.java-config"><a class="anchor" href="#jpa.java-config"></a>5.1.2. Annotation-based Configuration</h4>
<div class="paragraph">
<p>The Spring Data JPA repositories support can be activated not only through an XML namespace but also by using an annotation through JavaConfig, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 51. Spring Data JPA repositories using JavaConfig
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
class ApplicationConfig {

  @Bean
  public DataSource dataSource() {

    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.HSQL).build();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.acme.domain");
    factory.setDataSource(dataSource());
    return factory;
  }

  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> You must create <code class="notranslate">LocalContainerEntityManagerFactoryBean</code> and not <code class="notranslate">EntityManagerFactory</code> directly, since the former also participates in exception translation mechanisms in addition to creating <code class="notranslate">EntityManagerFactory</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The preceding configuration class sets up an embedded HSQL database by using the <code class="notranslate">EmbeddedDatabaseBuilder</code> API of <code class="notranslate">spring-jdbc</code>. Spring Data then sets up an <code class="notranslate">EntityManagerFactory</code> and uses Hibernate as the sample persistence provider. The last infrastructure component declared here is the <code class="notranslate">JpaTransactionManager</code>. Finally, the example activates Spring Data JPA repositories by using the <code class="notranslate">@EnableJpaRepositories</code> annotation, which essentially carries the same attributes as the XML namespace. If no base package is configured, it uses the one in which the configuration class resides.</p>
</div>
</div>
<div class="sect3">
<h4 id="jpa.bootstrap-mode"><a class="anchor" href="#jpa.bootstrap-mode"></a>5.1.3. Bootstrap Mode</h4>
<div class="paragraph">
<p>By default, Spring Data JPA repositories are default Spring beans. They are singleton scoped and eagerly initialized. During startup, they already interact with the JPA <code class="notranslate">EntityManager</code> for verification and metadata analysis purposes. Spring Framework supports the initialization of the JPA <code class="notranslate">EntityManagerFactory</code> in a background thread because that process usually takes up a significant amount of startup time in a Spring application. To make use of that background initialization effectively, we need to make sure that JPA repositories are initialized as late as possible.</p>
</div>
<div class="paragraph">
<p>As of Spring Data JPA 2.1 you can now configure a <code class="notranslate">BootstrapMode</code> (either via the <code class="notranslate">@EnableJpaRepositories</code> annotation or the XML namespace) that takes the following values:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">DEFAULT</code> (default) — Repositories are instantiated eagerly unless explicitly annotated with <code class="notranslate">@Lazy</code>. The lazification only has effect if no client bean needs an instance of the repository as that will require the initialization of the repository bean.</p> </li>
<li> <p><code class="notranslate">LAZY</code> — Implicitly declares all repository beans lazy and also causes lazy initialization proxies to be created to be injected into client beans. That means, that repositories will not get instantiated if the client bean is simply storing the instance in a field and not making use of the repository during initialization. Repository instances will be initialized and verified upon first interaction with the repository.</p> </li>
<li> <p><code class="notranslate">DEFERRED</code> — Fundamentally the same mode of operation as <code class="notranslate">LAZY</code>, but triggering repository initialization in response to an <code class="notranslate">ContextRefreshedEvent</code> so that repositories are verified before the application has completely started.</p> </li>
</ul>
</div>
<div class="sect4">
<h5 id="_recommendations"><a class="anchor" href="#_recommendations"></a>Recommendations</h5>
<div class="paragraph">
<p>If you’re not using asynchronous JPA bootstrap stick with the default bootstrap mode.</p>
</div>
<div class="paragraph">
<p>In case you bootstrap JPA asynchronously, <code class="notranslate">DEFERRED</code> is a reasonable default as it will make sure the Spring Data JPA bootstrap only waits for the <code class="notranslate">EntityManagerFactory</code> setup if that itself takes longer than initializing all other application components. Still, it makes sure that repositories are properly initialized and validated before the application signals it’s up.</p>
</div>
<div class="paragraph">
<p><code class="notranslate">LAZY</code> is a decent choice for testing scenarios and local development. Once you’re pretty sure that repositories will properly bootstrap, or in cases where you’re testing other parts of the application, executing verification for all repositories might just unnecessarily increase the startup time. The same applies to local development in which you only access parts of the application which might just need a single repository initialized.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jpa.entity-persistence"><a class="anchor" href="#jpa.entity-persistence"></a>5.2. Persisting Entities</h3>
<div class="paragraph">
<p>This section describes how to persist (save) entities with Spring Data JPA.</p>
</div>
<div class="sect3">
<h4 id="jpa.entity-persistence.saving-entites"><a class="anchor" href="#jpa.entity-persistence.saving-entites"></a>5.2.1. Saving Entities</h4>
<div class="paragraph">
<p>Saving an entity can be performed with the <code class="notranslate">CrudRepository.save(…)</code> method. It persists or merges the given entity by using the underlying JPA <code class="notranslate">EntityManager</code>. If the entity has not yet been persisted, Spring Data JPA saves the entity with a call to the <code class="notranslate">entityManager.persist(…)</code> method. Otherwise, it calls the <code class="notranslate">entityManager.merge(…)</code> method.</p>
</div>
<div class="sect4">
<h5 id="_entity_state_detection_strategies"><a class="anchor" href="#_entity_state_detection_strategies"></a>Entity State-detection Strategies</h5>
<div class="paragraph">
<p>Spring Data JPA offers the following strategies to detect whether an entity is new or not:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Id-Property inspection (<strong>default</strong>): By default Spring Data JPA inspects the identifier property of the given entity. If the identifier property is <code class="notranslate">null</code>, then the entity is assumed to be new. Otherwise, it is assumed to be not new.</p> </li>
<li> <p>Implementing <code class="notranslate">Persistable</code>: If an entity implements <code class="notranslate">Persistable</code>, Spring Data JPA delegates the new detection to the <code class="notranslate">isNew(…)</code> method of the entity. See the <a href="javascript:window.open('https://docs.spring.io/spring-data/data-commons/docs/current/api/index.html?org/springframework/data/domain/Persistable.html');" target="_blank" rel="noopener noreferrer">JavaDoc <i class="fa fa-external-link"></i></a> for details.</p> </li>
<li> <p>Implementing <code class="notranslate">EntityInformation</code>: You can customize the <code class="notranslate">EntityInformation</code> abstraction used in the <code class="notranslate">SimpleJpaRepository</code> implementation by creating a subclass of <code class="notranslate">JpaRepositoryFactory</code> and overriding the <code class="notranslate">getEntityInformation(…)</code> method accordingly. You then have to register the custom implementation of <code class="notranslate">JpaRepositoryFactory</code> as a Spring bean. Note that this should be rarely necessary. See the <a href="javascript:window.open('https://docs.spring.io/spring-data/data-jpa/docs/current/api/index.html?org/springframework/data/jpa/repository/support/JpaRepositoryFactory.html');" target="_blank" rel="noopener noreferrer">JavaDoc <i class="fa fa-external-link"></i></a> for details.</p> </li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jpa.query-methods"><a class="anchor" href="#jpa.query-methods"></a>5.3. Query Methods</h3>
<div class="paragraph">
<p>This section describes the various ways to create a query with Spring Data JPA.</p>
</div>
<div class="sect3">
<h4 id="jpa.sample-app.finders.strategies"><a class="anchor" href="#jpa.sample-app.finders.strategies"></a>5.3.1. Query Lookup Strategies</h4>
<div class="paragraph">
<p>The JPA module supports defining a query manually as a String or having it being derived from the method name.</p>
</div>
<div class="sect4">
<h5 id="_declared_queries"><a class="anchor" href="#_declared_queries"></a>Declared Queries</h5>
<div class="paragraph">
<p>Although getting a query derived from the method name is quite convenient, one might face the situation in which either the method name parser does not support the keyword one wants to use or the method name would get unnecessarily ugly. So you can either use JPA named queries through a naming convention (see <a href="#jpa.query-methods.named-queries">Using JPA Named Queries</a> for more information) or rather annotate your query method with <code class="notranslate">@Query</code> (see <a href="#jpa.query-methods.at-query">Using <code class="notranslate">@Query</code></a> for details).</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpa.query-methods.query-creation"><a class="anchor" href="#jpa.query-methods.query-creation"></a>5.3.2. Query Creation</h4>
<div class="paragraph">
<p>Generally, the query creation mechanism for JPA works as described in “<a href="#repositories.query-methods">Query methods</a>”. The following example shows what a JPA query method translates into:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 52. Query creation from method names
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="notranslate">public interface UserRepository extends Repository&lt;User, Long&gt; {

  List&lt;User&gt; findByEmailAddressAndLastname(String emailAddress, String lastname);
}</pre>
</div>
</div>
<div class="paragraph">
<p>We create a query using the JPA criteria API from this, but, essentially, this translates into the following query: <code class="notranslate">select u from User u where u.emailAddress = ?1 and u.lastname = ?2</code>. Spring Data JPA does a property check and traverses nested properties, as described in “<a href="#repositories.query-methods.query-property-expressions">Property Expressions</a>”.</p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following table describes the keywords supported for JPA and what a method containing that keyword translates to:</p>
</div>
<table class="tableblock frame-all grid-all fit-content">
<caption class="title">
Table 3. Supported keywords inside method names
</caption>
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Keyword</th>
<th class="tableblock halign-left valign-top">Sample</th>
<th class="tableblock halign-left valign-top">JPQL snippet</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">And</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByLastnameAndFirstname</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.lastname = ?1 and x.firstname = ?2</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Or</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByLastnameOrFirstname</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.lastname = ?1 or x.firstname = ?2</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Is,Equals</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstname</code>,<code class="notranslate">findByFirstnameIs</code>,<code class="notranslate">findByFirstnameEquals</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.firstname = ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Between</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByStartDateBetween</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.startDate between ?1 and ?2</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">LessThan</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeLessThan</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age &lt; ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">LessThanEqual</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeLessThanEqual</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age &lt;= ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">GreaterThan</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeGreaterThan</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age &gt; ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">GreaterThanEqual</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeGreaterThanEqual</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age &gt;= ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">After</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByStartDateAfter</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.startDate &gt; ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Before</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByStartDateBefore</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.startDate &lt; ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">IsNull</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeIsNull</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age is null</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">IsNotNull,NotNull</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAge(Is)NotNull</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age not null</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Like</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameLike</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.firstname like ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">NotLike</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameNotLike</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.firstname not like ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">StartingWith</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameStartingWith</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.firstname like ?1</code> (parameter bound with appended <code class="notranslate">%</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">EndingWith</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameEndingWith</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.firstname like ?1</code> (parameter bound with prepended <code class="notranslate">%</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Containing</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameContaining</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.firstname like ?1</code> (parameter bound wrapped in <code class="notranslate">%</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">OrderBy</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeOrderByLastnameDesc</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age = ?1 order by x.lastname desc</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Not</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByLastnameNot</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.lastname &lt;&gt; ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">In</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeIn(Collection&lt;Age&gt; ages)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age in ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">NotIn</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByAgeNotIn(Collection&lt;Age&gt; ages)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.age not in ?1</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">True</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByActiveTrue()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.active = true</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">False</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByActiveFalse()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where x.active = false</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">IgnoreCase</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameIgnoreCase</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">… where UPPER(x.firstame) = UPPER(?1)</code></p></td>
</tr>
</tbody>
</table>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> <code class="notranslate">In</code> and <code class="notranslate">NotIn</code> also take any subclass of <code class="notranslate">Collection</code> as aparameter as well as arrays or varargs. For other syntactical versions of the same logical operator, check “<a href="#repository-query-keywords">Repository query keywords</a>”. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="jpa.query-methods.named-queries"><a class="anchor" href="#jpa.query-methods.named-queries"></a>5.3.3. Using JPA Named Queries</h4>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The examples use the <code class="notranslate">&lt;named-query /&gt;</code> element and <code class="notranslate">@NamedQuery</code> annotation. The queries for these configuration elements have to be defined in the JPA query language. Of course, you can use <code class="notranslate">&lt;named-native-query /&gt;</code> or <code class="notranslate">@NamedNativeQuery</code> too. These elements let you define the query in native SQL by losing the database platform independence. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="_xml_named_query_definition"><a class="anchor" href="#_xml_named_query_definition"></a>XML Named Query Definition</h5>
<div class="paragraph">
<p>To use XML configuration, add the necessary <code class="notranslate">&lt;named-query /&gt;</code> element to the <code class="notranslate">orm.xml</code> JPA configuration file located in the <code class="notranslate">META-INF</code> folder of your classpath. Automatic invocation of named queries is enabled by using some defined naming convention. For more details, see below.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 53. XML named query configuration
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-xml" data-lang="xml">&lt;named-query name="User.findByLastname"&gt;
  &lt;query&gt;select u from User u where u.lastname = ?1&lt;/query&gt;
&lt;/named-query&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The query has a special name that is used to resolve it at runtime.</p>
</div>
</div>
<div class="sect4">
<h5 id="_annotation_based_configuration"><a class="anchor" href="#_annotation_based_configuration"></a>Annotation-based Configuration</h5>
<div class="paragraph">
<p>Annotation-based configuration has the advantage of not needing another configuration file to be edited, lowering maintenance effort. You pay for that benefit by the need to recompile your domain class for every new query declaration.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 54. Annotation-based named query configuration
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Entity
@NamedQuery(name = "User.findByEmailAddress",
  query = "select u from User u where u.emailAddress = ?1")
public class User {

}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_declaring_interfaces"><a class="anchor" href="#_declaring_interfaces"></a>Declaring Interfaces</h5>
<div class="paragraph">
<p>To allow execution of these named queries, specify the <code class="notranslate">UserRepository</code> as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 55. Query method declaration in UserRepository
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  List&lt;User&gt; findByLastname(String lastname);

  User findByEmailAddress(String emailAddress);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Spring Data tries to resolve a call to these methods to a named query, starting with the simple name of the configured domain class, followed by the method name separated by a dot. So the preceding example would use the named queries defined in the examlpe instead of trying to create a query from the method name.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpa.query-methods.at-query"><a class="anchor" href="#jpa.query-methods.at-query"></a>5.3.4. Using <code class="notranslate">@Query</code></h4>
<div class="paragraph">
<p>Using named queries to declare queries for entities is a valid approach and works fine for a small number of queries. As the queries themselves are tied to the Java method that executes them, you can actually bind them directly by using the Spring Data JPA <code class="notranslate">@Query</code> annotation rather than annotating them to the domain class. This frees the domain class from persistence specific information and co-locates the query to the repository interface.</p>
</div>
<div class="paragraph">
<p>Queries annotated to the query method take precedence over queries defined using <code class="notranslate">@NamedQuery</code> or named queries declared in <code class="notranslate">orm.xml</code>.</p>
</div>
<div class="paragraph">
<p>The following example shows a query created with the <code class="notranslate">@Query</code> annotation:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 56. Declare query at the query method using
<code class="notranslate">@Query</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  @Query("select u from User u where u.emailAddress = ?1")
  User findByEmailAddress(String emailAddress);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_using_advanced_like_expressions"><a class="anchor" href="#_using_advanced_like_expressions"></a>Using Advanced <code class="notranslate">LIKE</code> Expressions</h5>
<div class="paragraph">
<p>The query execution mechanism for manually defined queries created with <code class="notranslate">@Query</code> allows the definition of advanced <code class="notranslate">LIKE</code> expressions inside the query definition, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 57. Advanced
<code class="notranslate">like</code> expressions in @Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  @Query("select u from User u where u.firstname like %?1")
  List&lt;User&gt; findByFirstnameEndsWith(String firstname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, the <code class="notranslate">LIKE</code> delimiter character (<code class="notranslate">%</code>) is recognized, and the query is transformed into a valid JPQL query (removing the <code class="notranslate">%</code>). Upon query execution, the parameter passed to the method call gets augmented with the previously recognized <code class="notranslate">LIKE</code> pattern.</p>
</div>
</div>
<div class="sect4">
<h5 id="_native_queries"><a class="anchor" href="#_native_queries"></a>Native Queries</h5>
<div class="paragraph">
<p>The <code class="notranslate">@Query</code> annotation allows for running native queries by setting the <code class="notranslate">nativeQuery</code> flag to true, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 58. Declare a native query at the query method using @Query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
  User findByEmailAddress(String emailAddress);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Spring Data JPA does not currently support dynamic sorting for native queries, because it would have to manipulate the actual query declared, which it cannot do reliably for native SQL. You can, however, use native queries for pagination by specifying the count query yourself, as shown in the following example: </td>
</tr>
</tbody>
</table>
</div>
<div class="exampleblock">
<div class="title">
Example 59. Declare native count queries for pagination at the query method by using
<code class="notranslate">@Query</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page&lt;User&gt; findByLastname(String lastname, Pageable pageable);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>A similar approach also works with named native queries, by adding the <code class="notranslate">.count</code> suffix to a copy of your query. You probably need to register a result set mapping for your count query, though.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpa.query-methods.sorting"><a class="anchor" href="#jpa.query-methods.sorting"></a>5.3.5. Using Sort</h4>
<div class="paragraph">
<p>Sorting can be done be either providing a <code class="notranslate">PageRequest</code> or by using <code class="notranslate">Sort</code> directly. The properties actually used within the <code class="notranslate">Order</code> instances of <code class="notranslate">Sort</code> need to match your domain model, which means they need to resolve to either a property or an alias used within the query. The JPQL defines this as a state field path expression.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Using any non-referenceable path expression leads to an <code class="notranslate">Exception</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>However, using <code class="notranslate">Sort</code> together with <a href="#jpa.query-methods.at-query"><code class="notranslate">@Query</code></a> lets you sneak in non-path-checked <code class="notranslate">Order</code> instances containing functions within the <code class="notranslate">ORDER BY</code> clause. This is possible because the <code class="notranslate">Order</code> is appended to the given query string. By default, Spring Data JPA rejects any <code class="notranslate">Order</code> instance containing function calls, but you can use <code class="notranslate">JpaSort.unsafe</code> to add potentially unsafe ordering.</p>
</div>
<div class="paragraph">
<p>The following example uses <code class="notranslate">Sort</code> and <code class="notranslate">JpaSort</code>, including an unsafe option on <code class="notranslate">JpaSort</code>:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 60. Using
<code class="notranslate">Sort</code> and
<code class="notranslate">JpaSort</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  @Query("select u from User u where u.lastname like ?1%")
  List&lt;User&gt; findByAndSort(String lastname, Sort sort);

  @Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
  List&lt;Object[]&gt; findByAsArrayAndSort(String lastname, Sort sort);
}

repo.findByAndSort("lannister", new Sort("firstname"));               <i class="conum" data-value="1"></i><b>(1)</b>
repo.findByAndSort("stark", new Sort("LENGTH(firstname)"));           <i class="conum" data-value="2"></i><b>(2)</b>
repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)")); <i class="conum" data-value="3"></i><b>(3)</b>
repo.findByAsArrayAndSort("bolton", new Sort("fn_len"));              <i class="conum" data-value="4"></i><b>(4)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Valid <code class="notranslate">Sort</code> expression pointing to property in domain model.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Invalid <code class="notranslate">Sort</code> containing function call. Thows Exception.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Valid <code class="notranslate">Sort</code> containing explicitly <em>unsafe</em> <code class="notranslate">Order</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Valid <code class="notranslate">Sort</code> expression pointing to aliased function.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpa.named-parameters"><a class="anchor" href="#jpa.named-parameters"></a>5.3.6. Using Named Parameters</h4>
<div class="paragraph">
<p>By default, Spring Data JPA uses position-based parameter binding, as described in all the preceding examples. This makes query methods a little error-prone when refactoring regarding the parameter position. To solve this issue, you can use <code class="notranslate">@Param</code> annotation to give a method parameter a concrete name and bind the name in the query, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 61. Using named parameters
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends JpaRepository&lt;User, Long&gt; {

  @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
  User findByLastnameOrFirstname(@Param("lastname") String lastname,
                                 @Param("firstname") String firstname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The method parameters are switched according to their order in the defined query. </td>
</tr>
</tbody>
</table>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> As of version 4, Spring fully supports Java 8’s parameter name discovery based on the <code class="notranslate">-parameters</code> compiler flag. By using this flag in your build as an alternative to debug information, you can omit the <code class="notranslate">@Param</code> annotation for named parameters. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="jpa.query.spel-expressions"><a class="anchor" href="#jpa.query.spel-expressions"></a>5.3.7. Using SpEL Expressions</h4>
<div class="paragraph">
<p>As of Spring Data JPA release 1.4, we support the usage of restricted SpEL template expressions in manually defined queries that are defined with <code class="notranslate">@Query</code>. Upon query execution, these expressions are evaluated against a predefined set of variables. Spring Data JPA supports a variable called <code class="notranslate">entityName</code>. Its usage is <code class="notranslate">select x from #{#entityName} x</code>. It inserts the <code class="notranslate">entityName</code> of the domain type associated with the given repository. The <code class="notranslate">entityName</code> is resolved as follows: If the domain type has set the name property on the <code class="notranslate">@Entity</code> annotation, it is used. Otherwise, the simple class-name of the domain type is used.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates one use case for the <code class="notranslate">#{#entityName}</code> expression in a query string where you want to define a repository interface with a query method and a manually defined query:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 62. Using SpEL expressions in repository query methods - entityName
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Entity
public class User {

  @Id
  @GeneratedValue
  Long id;

  String lastname;
}

public interface UserRepository extends JpaRepository&lt;User,Long&gt; {

  @Query("select u from #{#entityName} u where u.lastname = ?1")
  List&lt;User&gt; findByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To avoid stating the actual entity name in the query string of a <code class="notranslate">@Query</code> annotation, you can use the <code class="notranslate">#{#entityName}</code> variable.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The <code class="notranslate">entityName</code> can be customized by using the <code class="notranslate">@Entity</code> annotation. Customizations in <code class="notranslate">orm.xml</code> are not supported for the SpEL expressions. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Of course, you could have just used <code class="notranslate">User</code> in the query declaration directly, but that would require you to change the query as well. The reference to <code class="notranslate">#entityName</code> picks up potential future remappings of the <code class="notranslate">User</code> class to a different entity name (for example, by using <code class="notranslate">@Entity(name = "MyUser")</code>.</p>
</div>
<div class="paragraph">
<p>Another use case for the <code class="notranslate">#{#entityName}</code> expression in a query string is if you want to define a generic repository interface with specialized repository interfaces for a concrete domain type. To not repeat the definition of custom query methods on the concrete interfaces, you can use the entity name expression in the query string of the <code class="notranslate">@Query</code> annotation in the generic repository interface, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 63. Using SpEL expressions in repository query methods - entityName with inheritance
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@MappedSuperclass
public abstract class AbstractMappedType {
  …
  String attribute
}

@Entity
public class ConcreteType extends AbstractMappedType { … }

@NoRepositoryBean
public interface MappedTypeRepository&lt;T extends AbstractMappedType&gt;
  extends Repository&lt;T, Long&gt; {

  @Query("select t from #{#entityName} t where t.attribute = ?1")
  List&lt;T&gt; findAllByAttribute(String attribute);
}

public interface ConcreteRepository
  extends MappedTypeRepository&lt;ConcreteType&gt; { … }</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the preceding example, the <code class="notranslate">MappedTypeRepository</code> interface is the common parent interface for a few domain types extending <code class="notranslate">AbstractMappedType</code>. It also defines the generic <code class="notranslate">findAllByAttribute(…)</code> method, which can be used on instances of the specialized repository interfaces. If you now invoke <code class="notranslate">findByAllAttribute(…)</code> on <code class="notranslate">ConcreteRepository</code>, the query becomes <code class="notranslate">select t from ConcreteType t where t.attribute = ?1</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="jpa.modifying-queries"><a class="anchor" href="#jpa.modifying-queries"></a>5.3.8. Modifying Queries</h4>
<div class="paragraph">
<p>All the previous sections describe how to declare queries to access a given entity or collection of entities. You can add custom modifying behavior by using the facilities described in “<a href="#repositories.custom-implementations">Custom Implementations for Spring Data Repositories</a>”. As this approach is feasible for comprehensive custom functionality, you can modify queries that only need parameter binding by annotating the query method with <code class="notranslate">@Modifying</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 64. Declaring manipulating queries
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Doing so triggers the query annotated to the method as an updating query instead of a selecting one. As the <code class="notranslate">EntityManager</code> might contain outdated entities after the execution of the modifying query, we do not automatically clear it (see the <a href="javascript:window.open('https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html');" target="_blank" rel="noopener noreferrer">JavaDoc <i class="fa fa-external-link"></i></a> of <code class="notranslate">EntityManager.clear()</code> for details), since this effectively drops all non-flushed changes still pending in the <code class="notranslate">EntityManager</code>. If you wish the <code class="notranslate">EntityManager</code> to be cleared automatically, you can set the <code class="notranslate">@Modifying</code> annotation’s <code class="notranslate">clearAutomatically</code> attribute to <code class="notranslate">true</code>.</p>
</div>
<div class="paragraph">
<p>The <code class="notranslate">@Modifying</code> annotation is only relevant in combination with the <code class="notranslate">@Query</code> annotation. Derived query methods or custom methods do not require this Annotation.</p>
</div>
<div class="sect4">
<h5 id="jpa.modifying-queries.derived-delete"><a class="anchor" href="#jpa.modifying-queries.derived-delete"></a>Derived Delete Queries</h5>
<div class="paragraph">
<p>Spring Data JPA also supports derived delete queries that let you avoid having to declare the JPQL query explicitly, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 65. Using a derived delete query
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface UserRepository extends Repository&lt;User, Long&gt; {

  void deleteByRoleId(long roleId);

  @Modifying
  @Query("delete from User u where user.role.id = ?1")
  void deleteInBulkByRoleId(long roleId);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Although the <code class="notranslate">deleteByRoleId(…)</code> method looks like it basically produces the same result as the <code class="notranslate">deleteInBulkByRoleId(…)</code>, there is an important difference between the two method declarations in terms of the way they get executed. As the name suggests, the latter method issues a single JPQL query (the one defined in the annotation) against the database. This means even currently loaded instances of <code class="notranslate">User</code> do not see lifecycle callbacks invoked.</p>
</div>
<div class="paragraph">
<p>To make sure lifecycle queries are actually invoked, an invocation of <code class="notranslate">deleteByRoleId(…)</code> executes a query and then deletes the returned instances one by one, so that the persistence provider can actually invoke <code class="notranslate">@PreRemove</code> callbacks on those entities.</p>
</div>
<div class="paragraph">
<p>In fact, a derived delete query is a shortcut for executing the query and then calling <code class="notranslate">CrudRepository.delete(Iterable&lt;User&gt; users)</code> on the result and keeping behavior in sync with the implementations of other <code class="notranslate">delete(…)</code> methods in <code class="notranslate">CrudRepository</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpa.query-hints"><a class="anchor" href="#jpa.query-hints"></a>5.3.9. Applying Query Hints</h4>
<div class="paragraph">
<p>To apply JPA query hints to the queries declared in your repository interface, you can use the <code class="notranslate">@QueryHints</code> annotation. It takes an array of JPA <code class="notranslate">@QueryHint</code> annotations plus a boolean flag to potentially disable the hints applied to the additional count query triggered when applying pagination, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 66. Using QueryHints with a repository method
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">public interface UserRepository extends Repository&lt;User, Long&gt; {

  @QueryHints(value = { @QueryHint(name = "name", value = "value")},
              forCounting = false)
  Page&lt;User&gt; findByLastname(String lastname, Pageable pageable);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The preceding declaration would apply the configured <code class="notranslate">@QueryHint</code> for that actually query but omit applying it to the count query triggered to calculate the total number of pages.</p>
</div>
</div>
<div class="sect3">
<h4 id="jpa.entity-graph"><a class="anchor" href="#jpa.entity-graph"></a>5.3.10. Configuring Fetch- and LoadGraphs</h4>
<div class="paragraph">
<p>The JPA 2.1 specification introduced support for specifying Fetch- and LoadGraphs that we also support with the <code class="notranslate">@EntityGraph</code> annotation, which lets you reference a <code class="notranslate">@NamedEntityGraph</code> definition. You can use that annotation on an entity to configure the fetch plan of the resulting query. The type (<code class="notranslate">Fetch</code> or <code class="notranslate">Load</code>) of the fetching can be configured by using the <code class="notranslate">type</code> attribute on the <code class="notranslate">@EntityGraph</code> annotation. See the JPA 2.1 Spec 3.7.4 for further reference.</p>
</div>
<div class="paragraph">
<p>The following example shows how to define a named entity graph on an entity:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 67. Defining a named entity graph on an entity.
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Entity
@NamedEntityGraph(name = "GroupInfo.detail",
  attributeNodes = @NamedAttributeNode("members"))
public class GroupInfo {

  // default fetch mode is lazy.
  @ManyToMany
  List&lt;GroupMember&gt; members = new ArrayList&lt;GroupMember&gt;();

  …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows how to reference a named entity graph on a repository query method:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 68. Referencing a named entity graph definition on a repository query method.
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Repository
public interface GroupRepository extends CrudRepository&lt;GroupInfo, String&gt; {

  @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD)
  GroupInfo getByGroupName(String name);

}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>It is also possible to define ad hoc entity graphs by using <code class="notranslate">@EntityGraph</code>. The provided <code class="notranslate">attributePaths</code> are translated into the according <code class="notranslate">EntityGraph</code> without needing to explicitly add <code class="notranslate">@NamedEntityGraph</code> to your domain types, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 69. Using AD-HOC entity graph definition on an repository query method.
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">@Repository
public interface GroupRepository extends CrudRepository&lt;GroupInfo, String&gt; {

  @EntityGraph(attributePaths = { "members" })
  GroupInfo getByGroupName(String name);

}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="projections"><a class="anchor" href="#projections"></a>5.3.11. Projections</h4>
<div class="paragraph">
<p>Spring Data query methods usually return one or multiple instances of the aggregate root managed by the repository. However, it might sometimes be desirable to create projections based on certain attributes of those types. Spring Data allows modeling dedicated return types, to more selectively retrieve partial views of the managed aggregates.</p>
</div>
<div class="paragraph">
<p>Imagine a repository and aggregate root type such as the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 70. A sample aggregate and repository
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">class Person {

  @Id UUID id;
  String firstname, lastname;
  Address address;

  static class Address {
    String zipCode, city, street;
  }
}

interface PersonRepository extends Repository&lt;Person, UUID&gt; {

  Collection&lt;Person&gt; findByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Now imagine that we want to retrieve the person’s name attributes only. What means does Spring Data offer to achieve this? The rest of this chapter answers that question.</p>
</div>
<div class="sect4">
<h5 id="projections.interfaces"><a class="anchor" href="#projections.interfaces"></a>Interface-based Projections</h5>
<div class="paragraph">
<p>The easiest way to limit the result of the queries to only the name attributes is by declaring an interface that exposes accessor methods for the properties to be read, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 71. A projection interface to retrieve a subset of attributes
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface NamesOnly {

  String getFirstname();
  String getLastname();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The important bit here is that the properties defined here exactly match properties in the aggregate root. Doing so lets a query method be added as follows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 72. A repository using an interface based projection with a query method
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonRepository extends Repository&lt;Person, UUID&gt; {

  Collection&lt;NamesOnly&gt; findByLastname(String lastname);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The query execution engine creates proxy instances of that interface at runtime for each element returned and forwards calls to the exposed methods to the target object.</p>
</div>
<div id="projections.interfaces.nested" class="paragraph">
<p>Projections can be used recursively. If you want to include some of the <code class="notranslate">Address</code> information as well, create a projection interface for that and return that interface from the declaration of <code class="notranslate">getAddress()</code>, as shown in the following example:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 73. A projection interface to retrieve a subset of attributes
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface PersonSummary {

  String getFirstname();
  String getLastname();
  AddressSummary getAddress();

  interface AddressSummary {
    String getCity();
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>On method invocation, the <code class="notranslate">address</code> property of the target instance is obtained and wrapped into a projecting proxy in turn.</p>
</div>
<div class="sect5">
<h6 id="projections.interfaces.closed"><a class="anchor" href="#projections.interfaces.closed"></a>Closed Projections</h6>
<div class="paragraph">
<p>A projection interface whose accessor methods all match properties of the target aggregate is considered to be a closed projection. The following example (which we used earlier in this chapter, too) is a closed projection:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 74. A closed projection
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface NamesOnly {

  String getFirstname();
  String getLastname();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If you use a closed projection, Spring Data can optimize the query execution, because we know about all the attributes that are needed to back the projection proxy. For more details on that, see the module-specific part of the reference documentation.</p>
</div>
</div>
<div class="sect5">
<h6 id="projections.interfaces.open"><a class="anchor" href="#projections.interfaces.open"></a>Open Projections</h6>
<div class="paragraph">
<p>Accessor methods in projection interfaces can also be used to compute new values by using the <code class="notranslate">@Value</code> annotation, as shown in the following example:</p>
</div>
<div id="projections.interfaces.open.simple" class="exampleblock">
<div class="title">
Example 75. An Open Projection
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight notranslate"><code class="language-java" data-lang="java">interface NamesOnly {

  @Value("#{target.firstname + ' ' + target.lastname}")
  String getFullName();
  …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The aggregate root backing the projection is available in the <code class="notranslate">target</code> variable. A projection interface using <code class="notranslate">@Value</code> is an open projection. Spring Data cannot apply query execution optimizations in this case, because the SpEL expression could use any attribute of the aggregate root.</p>
</div>
<div class="paragraph">
<p>The expressions used in <code class="notranslate">@Value</code> should not be too complex — you want to avoid programming in <code class="notranslate">String</code> variables. For very simple expressions, one option might be to resort to default methods (introduced in Java 8), as shown in the following example:</p>
</div>
<div id="projections.interfaces.open.default" class="exampleblock">
<div class="title">
Example 76. A projection interface using a default method for custom logic
</div>
<div class="content">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div></div>
</div>
</section>
<div class="right-sidebar">
<div class="affix"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6108808167664152" data-ad-slot="3102929424" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
</div>
</div>
<div class="ft">
<a href="#toolbar-title" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a>
<footer class="footer">
<div class="footer__container--normal">
<img alt="扫码关注公众号" title="扫码关注公众号" src="static/picture/qr-code.png" width="170" height="170">
<div class="footer__description--normal">
<p class="paragraph footer__author--normal">Docs4dev<sup class="super">&#xAE;</sup>
</p>
<p class="paragraph footer__quote&#45;&#45;normal">
如果你在使用过程中遇到任何问题，可以在 <a href="javascript:window.open('https://github.com/docs4dev/docs4dev-issues');" target="_blank" rel="noopener noreferrer">这里<i class="fa fa-external-link"></i></a> 提issue。
</p>
<div class="footer__main--normal">
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
<a href="javascript:window.open('https://beian.miit.gov.cn/');">
蜀ICP备14021783号-6
</a>
</p>
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
Copyright &#xA9; Docs4dev all
right reserved, powered by <a href="index2.html" target="_blank">Docs4dev</a></p>
</div>
</div>
</div>
<div class="box__issues">
</div>
</footer>
</div>
</div>
</div>
</div>
</div>
<script>
  var hasToc = true;
  /*  var downloadable = /!*false*!/ false;
    var editable = /!*false*!/ false;
    var code = /!*"spring-data-jpa"*!/ false;
    var version = /!*"2.1.5.RELEASE"*!/ false;
    var type = /!*"reference"*!/ false;
    var lang = /!*"en"*!/ 'en';
    //edit link
    require(["gitbook", "jQuery"], function (gitbook, $) {
      gitbook.events.bind('start', function (e, config) {
        // Add edit toolbar to left
        var chapterId = /!*16321*!/ 0;
        if (downloadable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-download',
            text: '下载',
            onClick: function () {
              window.open('/download?code=' + code + '&version=' + version + '&type=' + type + '&lang=' + lang);
            }
          });
        }
        if (editable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-edit',
            text: '编辑此页',
            onClick: function () {
              window.open('/docs/edit?chapterId=' + chapterId + '&lang=' + lang);
            }
          });
        }
      });
    });*/
</script>
<script>
    var code = "spring-data-jpa";
    var lang = "en";
  </script>

<script src="static/js/autocomplete-js.js"></script>
<script src="static/js/app.min.js"></script>
<script src="static/js/search.min.js"></script>
</body>
</html>
